Results
Results are now for eight species managed under Mid-Atlantic Council Management Plans according to NOAA.
State allocations of the commercial black sea bass coastwide quota were originally implemented in 2003 as part of Amendment 13, loosely based on historical landings from 1980- 2001.
Scomber scombrus, Peprilus triacanthus (butterfish), Illex illecebrosus (shortfin squid), Paralichthys dentatus (summer flounder), Stenotomus chrysops (Scoop), Centropristis striata (black sea bass), Pomatomus saltatrix (Bluefish), Lopholatilus chamaeleonticeps (Golden tilefish), Caulolatilus microps (blueline tilefish) and Clupea harengus
# Spatial data
States <- c("maine", "new hampshire", "massachusetts", "connecticut", "rhode island", "new york", "new jersey", "delaware", "maryland", "virginia", "north carolina")
# US State Map (land)
land_sf <- st_as_sf(map("state", plot = FALSE, fill = TRUE)) %>%
filter(ID %in% States) %>%
mutate(abrev = c("CT","DE","ME","MD","MA","NH","NJ","NY","NC","RI","VA"),
state = str_to_sentence(ID)
)
# US EEZ map
path_world <- my_path("G", extra_path = "Spatial/SAU/SAU_Shapefile", name = "SAUEEZ_July2015.shp")
### Previouslly created grids
grids <- my_path("D", "Spatial/grid_eez_fp", name = "grid_eez_fp_df.csv", read = T) %>%
mutate(
spatial = "fp"
) %>%
bind_rows(
my_path("D", "Spatial/grid_eez_sw", name = "grid_eez_sw_df.csv", read = T)
) %>%
select(-spp) %>%
mutate(
spatial = ifelse(is.na(spatial),"sw",spatial)
) %>%
distinct(.keep_all = T)
# Species data
# Managed species by Mid-Atlantic Council Management Plans, and State waters
# https://www.fisheries.noaa.gov/new-england-mid-atlantic/commercial-fishing/new-england-mid-atlantic-fishery-management-plans
Species <- c(
"Paralichthys dentatus", #summer flounder
"Stenotomus chrysops", #Scup"
"Centropristis striata"#, # black sea bass
)
spp_paths <- list.files(my_path("R",extra_path = "Partial/Interpolation/"))
# Some gibiris for names
taxon_list <- gsub("_"," ",spp_paths)
taxon_list <- gsub("tif ","",taxon_list)
taxon_list <- gsub(".csv","",taxon_list)
taxon_list <- taxon_list[taxon_list %in% Species]
# Now set a list of files to read
taxon_read <- paste0("tif_",taxon_list,".csv")
taxon_read <- gsub(" ","_",taxon_read)
taxon_read <- spp_paths[spp_paths %in% taxon_read]
#### Load sw interpolation
taxon_sw <- my_path("R",extra_path = "Partial/Interpolation/", name = taxon_read)
# Load all sp in one table
historic_spp <- bind_rows(lapply(taxon_sw, fread)) %>%
left_join(grids,
by = c("index","lon","lat")
) %>%
filter(!is.na(spatial)) %>%
mutate(
season = ifelse(str_detect(region,"Spring"),"Spring","Fall"),
label = ifelse(spp == "Paralichthys dentatus" & year >= 1980 & year <= 1986,"Reference",
ifelse(spp == "Stenotomus chrysops" & year >= 1988 & year <= 1992,"Reference",
ifelse( spp =="Centropristis striata" & year >= 1980 & year <= 2001,"Reference",
ifelse(year > 2001,"Today",NA)
)
)
)
)
# historic_spp %>%
# filter(is.na(spatial)) %>%
# filter(year == 1973,
# region == "Northeast US Fall") %>%
# ggplot() +
# geom_tile(
# aes(
# x = lon,
# y = lat,
# fill = index
# )
# ) +
# facet_grid(spp~state) +
# geom_sf(data = land_sf,aes()) +
# geom_sf(data = eez_sf, aes(), fill =NA)
unique(historic_spp$spp)
unique(historic_spp$region)
unique(historic_spp$season)
# Periods
periods <-tibble(
order = c(rep("a",12),
rep("b",12),
rep("c",12),
rep("d",11)
),
label = c(rep("1973-1984",12),
rep("1985-1996",12),
rep("1997-2008",12),
rep("2009-2019",11)
),
year = c(seq(1973,1984,1),
seq(1985,1996,1),
seq(1997,2008,1),
seq(2009,2019,1)
)
)
state_lat <- historic_spp %>%
group_by(state) %>%
summarise(
order = mean(lat)
) %>%
filter(!is.na(state)) %>%
mutate(abrev = c("CT","DE","ME","MD","MA","NH","NJ","NY","NC","RI","VA")
) %>%
arrange(desc(order)) %>%
mutate(lat = order,
# order = letters[1:11],
order = c("b","a",letters[3:11]),)
# State pallet
state_pallet <- c(wes_palette(n = 5, name = "Darjeeling1"),
wes_palette(n = 5, name = "Darjeeling2"),
# wes_palette(n = 2, name = "GrandBudapest1")
"#FD6467"
)
# print for notebook
head(historic_spp)
Regulatory units result
#### Data needed ####
# Get state order from North to south
state_order <- my_path("D","Spatial/grid_eez_sw", name = "grid_eez_sw_df.csv",read = T) %>%
group_by(state) %>%
summarise(
order = mean(lat)
) %>%
mutate(abrev = c("CT","DE","ME","MD","MA","NH","NJ","NY","NC","RI","VA")
) %>%
arrange(desc(order)) %>%
mutate(order= c("b","a",letters[3:11])) %>% # weirdly maine goes below
arrange(order)
# Load grid of state waters
grid_eez_sw_sf <- st_read(my_path("D","Spatial/grid_eez_sw", name = "grid_eez_sw_sf.shp")) %>%
select(index,state,geometry) %>%
mutate(method = "state_waters",
state = str_to_sentence(state)) %>%
left_join(state_order)
grid_eez_sw_sf$group <- factor(grid_eez_sw_sf$abrev, # Reordering group factor levels
levels = state_order$abrev)
# Load grid of fishing ports
grid_eez_fp_sf <- st_read(my_path("D","Spatial/grid_eez_fp", name = "grid_eez_fp.shp")) %>%
select(index,abrev=lndng_s,geometry) %>%
mutate(method = "fishing_port"#,
# state = str_to_sentence(landing_port)
)%>%
left_join(state_order)
grid_eez_fp_sf$group <- factor(grid_eez_fp_sf$abrev, # Reordering group factor levels
levels = state_order$abrev)
grid_eez_fp_sf <- arrange(grid_eez_fp_sf,group)
# Plotting
# Make sure st_simplify() is run for eez sf
# State waters plot
p_sw <- gridExtra::grid.arrange(
# Overall (overlapping) position
ggplot(grid_eez_sw_sf) +
geom_sf(data = eez_sf, aes(), fill = "white") +
geom_sf(aes(color =group , fill = group), alpha = 0.3) +
geom_sf(data = land_sf, aes()) +
ggsflabel::geom_sf_label_repel(data = land_sf, aes(label= abrev),
size = 4,
box.padding = 0.10,
hjust = 1) +
scale_color_manual(values = state_pallet) +
scale_fill_manual(values = state_pallet) +
my_ggtheme_p(leg_pos = "",
ax_tx_s = 13) +
coord_sf(ylim = c(30,48)) +
scale_y_continuous(breaks = c(30,35,40,45))+
labs(x = "", y = "", title = "A) State waters approach") +
theme(plot.title = element_text(size = 20)),
# Showing each state separately
ggplot(grid_eez_sw_sf) +
geom_sf(data = land_sf, aes(), fill = "grey80") +
geom_sf(aes(color = group),size = 0.1, alpha = 0.3) +
facet_wrap(~ group) +
theme(legend.position = "top") +
scale_color_manual(values = state_pallet,
# labels = unique(grid_eez_sw_sf$group)) +
labels = grid_eez_sw_sf %>% arrange(order) %>% pull(state) %>% unique()) +
ggtitle("") +
my_ggtheme_p(leg_pos = "",
ax_tx_s = 11,
axx_tx_ang = 45,
hjust = 1
),
nrow = 1)
##### ------------- ####
# Fishing Ports plot
##### ------------- ####
grid_eez_fp_sf <-
grid_eez_sw_sf %>%
filter(!group %in% grid_eez_fp_sf$group) %>%
mutate(index = NA) %>%
bind_rows(grid_eez_fp_sf)
p_fp <- gridExtra::grid.arrange(
# Overall (overlapping) position
ggplot(data = subset(grid_eez_fp_sf, index != "NA")) +
geom_sf(data = eez_sf, aes(), fill = "white") +
geom_sf(aes(color = group, fill = abrev), alpha = 0.3) +
geom_sf(data = land_sf, aes()) +
ggsflabel::geom_sf_label_repel(data = land_sf, aes(label= abrev),
size = 4,
box.padding = 0.10,
hjust = 1) +
# scale_color_manual(values = state_pallet) +
# scale_fill_manual(values = state_pallet) +
scale_color_manual(values = c(state_pallet[3:4],state_pallet[6:13])) +
scale_fill_manual(values = c(state_pallet[3:4],state_pallet[6:13])) +
my_ggtheme_p(leg_pos = "",
ax_tx_s = 13) +
coord_sf(ylim = c(30,48)) +
scale_y_continuous(breaks = c(30,35,40,45)) +
labs(x = "", y = "", title = "B) Fishing ports approach") +
theme(plot.title = element_text(size = 20)),
# Showing each state separately
ggplot() +
geom_sf(data = subset(grid_eez_fp_sf, index = "NA"), color = "white") +
geom_sf(data = subset(grid_eez_fp_sf, index != "NA"), aes(color = group),size = 0.1, alpha = 0.3) +
geom_sf(data = land_sf, aes(), fill = "grey80") +
facet_wrap(~ group) +
geom_point(data = rename(ports_df, group = landing_state), aes(x = lon, y = lat), color = "#E6A0C4") +
theme(legend.position = "top") +
# scale_color_manual(values = state_pallet,
scale_color_manual(values = c(state_pallet[3:4],state_pallet[6:13]),
# labels = unique(grid_eez_fp_sf$group)) +
labels = grid_eez_fp_sf %>% arrange(order) %>% pull(state) %>% unique()) +
ggtitle("") +
my_ggtheme_p(leg_pos = "",
ax_tx_s = 11,
axx_tx_ang = 45,
hjust = 1
),
nrow = 1)
combined_plot <- gridExtra::grid.arrange(p_sw,p_fp,
bottom = "Longitude",
left = "Latitude")
ggsave(filename = "buffer_figure.jpg",
plot = combined_plot,
path = my_path("R","Figures"),
width = 11,
height = 11
)
Interpolation result
# Interpolation data
interpol_result <- historic_spp %>%
filter(!is.na(label)) %>%
group_by(label,index,spp,season,lat,lon) %>%
summarise(mean_cpue = mean(value,na.rm=T)) %>%
filter(!is.na(mean_cpue))
# Paper numbers
# interpol_result %>%
# filter(mean_cpue >0) %>%
# View()
# --------------------- #
# Biomass Centroid shift
# --------------------- #
# Estimate total interpolation
total_inter <- historic_spp %>%
filter(!is.na(label)) %>%
group_by(spp,index,season) %>%
summarise(mean_cpue = mean(value,na.rm=T)) %>%
group_by(spp,season) %>%
summarise(total_cpue = sum(mean_cpue, na.rm = T))
# Estimate centroid based on top 10 grids with higer abundance
centroid_db <- historic_spp %>%
filter(!is.na(label)) %>%
group_by(label,index,spp,season,lat,lon) %>%
summarise(mean_cpue = mean(value,na.rm=T)) %>%
filter(!is.na(mean_cpue)) %>%
left_join(total_inter) %>%
mutate(
per_cpue = round((mean_cpue/total_cpue)*100,2)
) %>%
group_by(spp,label,season) %>%
top_n(10,per_cpue) %>%
group_by(spp,label,season) %>%
summarise(
lat = mean(lat),
lon = mean(lon)
)
# Paper numbers
# centroid_db %>%
# select(-lon) %>%
# spread(label,lat) %>%
# mutate(diff = Today-Reference) %>%
# View()
# For alternative color pallet
pal <- wes_palette("Zissou1",100,type = "continuous")
inter_map <- ggplot() +
geom_tile(data = subset(interpol_result, mean_cpue == 0),
aes(
x = lon,
y = lat
),
fill = "grey90",
color = "grey90"
) +
geom_tile(data = subset(interpol_result, mean_cpue > 0),
aes(
x = lon,
y = lat,
fill = log10(mean_cpue),
color = log10(mean_cpue)
# fill = mean_cpue,
# color = mean_cpue
)
) +
geom_point(data = centroid_db,
aes(
x = lon,
y = lat
),
shape = 3,
color = "white"
) +
geom_sf(data = land_sf,aes()) +
labs(x = "Longitude",
y = "Latitude") +
# ggsflabel::geom_sf_label_repel(data = land_sf, aes(label= abrev),
# size = 4,
# box.padding = 0.10,
# hjust = 1) +
# Viridis option
# scale_fill_viridis("CPUE",
# limits = c(0,40),
# # limits = c(-5,1), # for log10
# direction = -1,
# end = 0.9
# ) +
# scale_color_viridis("CPUE",
# limits = c(0,40),
# # limits = c(-5,1), # for log10
# direction = -1,
# end = 0.9
# ) +
# wes anderson option
scale_fill_gradientn("CPUE",
colours = pal,
# limits = c(0,40) # For cpue
limits = c(-5,1) # for log10
) +
scale_color_gradientn("CPUE",
colours = pal,
# limits = c(0,40) # for cpue
limits = c(-5,1) # for log10
) +
facet_grid(spp~season+label) +
my_ggtheme_m(map_type = "na", leg_pos = "right",ax_tx_s = 7,ax_tl_s = 10,leg_tx_s = 12) #+
# theme(legend.key.width = unit(3,"line"))
ggsave("interpolation_wa.jpg",
inter_map,
path = my_path("R","Figures"),
width = 9,
height = 7)
Average proportion
This map shows the aggregated extrapolated value from all three species per State average across the whole study period within each State’s water.
Note: This is intended to be a supplemental figure
data_grid <- historic_spp %>%
group_by(state,lat,lon,region,spatial) %>%
summarise(sum = sum(value,na.rm= T), .groups = "drop") %>% # sum of all species
group_by(state,lat,lon,region,spatial) %>%
summarise(mean = mean(sum,na.rm= T), .groups = "drop") # average of all years
ggplot(data = subset(data_grid, !is.na(mean))) +
geom_tile(
aes(
x = lon,
y = lat,
fill = mean,
col = mean
)
) +
geom_sf(data = land_sf, aes()) +
facet_wrap(~ state + region + spatial) +
labs(x = "Longitude", y = "Latitude") +
scale_fill_viridis("Mean Interpolation", alpha = 0.8) +
scale_color_viridis("Mean Interpolation", alpha = 0.8) +
theme_bw()
Proportion Change
Here we show the average proportion of the interpolation by State and time period. Time periods were arbitrary defined as;
- Early; 1973 to 1984
- Mid; 1985 to 1997
- Late; 1998 to 2011
- Now; 2012 to 2019
Notes: Figure represents the Spring survey. This computation considers the Overlapping of state waters.
Data preparation
total_fited <- historic_spp %>%
group_by(year,season,spp,spatial) %>%
summarise(total_value = sum(value,na.rm=T),.groups = "drop")
state_fit <- historic_spp %>%
group_by(state,year,label,season,spp,spatial) %>%
summarise(state_value = sum(value,na.rm= T), .groups = "drop") %>%
# View()
left_join(total_fited,
by = c("year","season","spp","spatial")) %>%
mutate(percentage = state_value/total_value*100) %>%
group_by(state,label,season,spp,spatial) %>%
summarise(mean_per = round(mean(percentage)),.groups = "drop") %>%
#Only show results for spring
filter(!is.na(label))
Regulatory units map
reg_unit <- state_fit %>%
filter(season == "Spring") %>%
spread(spatial,mean_per) %>%
# Set NA's to 0 because no data found on FP
mutate(fp = replace_na(fp,0)) %>%
# View()
mutate(
difference = abs(fp-sw),
difference = ifelse(difference > 100,100,
ifelse(difference < -100,-100,difference)
)
) %>%
gather("spatial","mean_per",fp:difference) %>%
mutate(spp = gsub(" ","\n",spp),
spatial = ifelse(spatial == "fp","Fishing ports",
ifelse(spatial == "sw","State waters","Difference")
)
)
# The plot
map_plot <- land_sf %>%
left_join(reg_unit,
by = "state") %>%
filter(spatial != "Difference") %>%
ggplot() +
geom_sf(aes(fill = mean_per)) +
viridis::scale_fill_viridis("Average proportion per State", alpha = 0.8,
breaks = seq(0,35,5),
limits=(c(0,35))
)+
facet_grid(spatial~ spp+label) +
labs(x = "",
y = "") +
my_ggtheme_p(facet_tx_s = 20,
leg_pos = "bottom",
axx_tx_ang = 45,
ax_tx_s = 12,
ax_tl_s = 18,
hjust = 1) +
theme(legend.key.width = unit(4,"line"))
diff_plot <- land_sf %>%
left_join(reg_unit,
by = "state") %>%
filter(spatial == "Difference") %>%
ggplot() +
geom_sf(aes(fill = mean_per)) +
viridis::scale_fill_viridis("Difference (%)", alpha = 0.8,option = "C",
breaks = seq(0,20,5),
limits=(c(0,22)),
# labels = c("<-10",seq(-75,75,25),">100")
) +
facet_grid(spatial~ spp+label) +
labs(x = "",
y = "") +
my_ggtheme_p(facet_tx_s = 20,
leg_pos = "bottom",
axx_tx_ang = 45,
ax_tx_s = 12,
ax_tl_s = 18,
hjust = 1) +
theme(legend.key.width = unit(4,"line"),
strip.background = element_blank(),
strip.text.x = element_blank()
)
# Cowplot option
p <- ggdraw() +
# Revenue circular
draw_plot(map_plot, x = 0, y = 0.2, width = 1, height = 0.8) +
# Catch circular
draw_plot(diff_plot, x = 0, y = 0, width = 1, height = 0.4) +
draw_plot_label(label = c("Latitude", "Longitude"),
size = 18,
angle = c(90,0),
x = c(0,0.45),
y = c(0.45,0.15)
)
save_plot(
path = my_path("R","Figures"),
"proportion_chg_reg.jpg",
p,
base_height = 14,
base_width = 14
)
reg_unit %>%
# filter(spatial == "fp") %>%
select(-fp) %>%
spread(label,sw) %>%
mutate(
difference = Today-Reference
) %>%
gther(Reference:difference)
Seasonal units map
# Get seasonal data
season_fit <- state_fit %>%
filter(spatial != "fp") %>%
spread(season,mean_per) %>%
mutate(
Difference = abs(Fall-Spring),
Difference = ifelse(Difference > 100,100,
ifelse(Difference < -100,-100,Difference)
)
) %>%
gather("season","mean_per",Fall:Difference) %>%
mutate(spp = gsub(" ","\n",spp))
# The plot
map_plot <- land_sf %>%
left_join(season_fit,
by = "state") %>%
filter(season != "Difference") %>%
ggplot() +
geom_sf(aes(fill = mean_per)) +
viridis::scale_fill_viridis("Average proportion per State", alpha = 0.8,
breaks = seq(0,15,5),
limits=(c(0,15))
)+
facet_grid(season~ spp+label) +
labs(x = "",
y = "") +
my_ggtheme_p(facet_tx_s = 20,
leg_pos = "bottom",
axx_tx_ang = 45,
ax_tx_s = 12,
ax_tl_s = 18,
hjust = 1) +
theme(legend.key.width = unit(4,"line"))
diff_plot <- land_sf %>%
left_join(season_fit,
by = "state") %>%
filter(season == "Difference") %>%
ggplot() +
geom_sf(aes(fill = mean_per)) +
viridis::scale_fill_viridis("Difference (%)", alpha = 0.8,option = "C",
breaks = seq(0,5,1),
limits=(c(0,5)),
# labels = c("<-10",seq(-75,75,25),">100")
) +
facet_grid(season~ spp+label) +
labs(x = "",
y = "") +
my_ggtheme_p(facet_tx_s = 20,
leg_pos = "bottom",
axx_tx_ang = 45,
ax_tx_s = 12,
ax_tl_s = 18,
hjust = 1) +
theme(legend.key.width = unit(4,"line"),
strip.background = element_blank(),
strip.text.x = element_blank()
)
# Cowplot option
p <- ggdraw() +
# Revenue circular
draw_plot(map_plot, x = 0, y = 0.2, width = 1, height = 0.8) +
# Catch circular
draw_plot(diff_plot, x = 0, y = 0, width = 1, height = 0.4) +
draw_plot_label(label = c("Latitude", "Longitude"),
size = 18,
angle = c(90,0),
x = c(0,0.45),
y = c(0.45,0.15)
)
save_plot(
path = my_path("R","Figures"),
"proportion_chg_seas_.jpg",
p,
base_height = 14,
base_width = 14
)
Area plot
This graph shows the proportion of the interpolation value each State has over time.
Note: This plot is interactive. For ease comparison between States you can;
- One click on any State to remove it from the plot
- Two clicks on any State to isolate it from the plot (other states can then be added by just clicking on them).
- The bottom panel allows you to reduce the time frame
Dynamic aggregated plot
total_fited <- historic_spp %>%
group_by(year,region) %>%
summarise(total_value = sum(value,na.rm=T),.groups = "drop")
# group by state
state_fit <- historic_spp %>%
group_by(state,year,region) %>%
summarise(state_value = sum(value,na.rm= T), .groups = "drop") %>%
left_join(total_fited,
by = c("year","region")) %>%
mutate(percentage = state_value/total_value*100)
# Plot me
p <- ggplot(state_fit) +
geom_area(
aes(
x = year,
y = round(percentage),
fill = state
)
) +
ylab("Percentage (%)") +
# viridis::scale_fill_viridis(discrete = T, alpha = 0.8) +
scale_fill_manual(values = state_pallet) +
MyFunctions::my_ggtheme_p() +
facet_wrap(~region, ncol = 1) +
theme_dark()
ggplotly(p,
dynamicTicks = TRUE) %>%
layout(hovermode = "x") %>%
rangeslider()
Area plot (running mean)
This graph shows the proportion of each State smoothed over a *10 years running mean**. It allows to better see increasing and decreasing trends.
Dynamic aggregated plot
Note: This plot is also interactive and thus, follows the same options of the previous one.
# group by state
state_fit <- historic_spp %>%
group_by(state,year,region,.groups = "drop") %>%
summarise(state_value = sum(value,na.rm= T), .groups = "drop") %>%
left_join(total_fited,
by = c("year","region")) %>%
mutate(percentage = state_value/total_value*100) %>%
group_by(state,region) %>%
mutate(RMean = zoo::rollmean(x = percentage,
10,
fill = NA,
na.rm=T)
) %>%
left_join(state_lat)
# Plot me
p <- ggplot(state_fit) +
geom_area(
aes(
x = year,
y = round(RMean),
fill = state
# fill = order
)
) +
ylab("10 yrs running average (%)") +
scale_fill_manual(
"State",
values = state_pallet,
# labels = state_fit %>% arrange(order) %>% pull(state) %>% unique()
) +
MyFunctions::my_ggtheme_p() +
facet_wrap(~region, ncol = 1) +
theme_dark()
suppressWarnings(
ggplotly(p,
dynamicTicks = TRUE) %>%
layout(hovermode = "x") %>%
# add_trace() %>%
rangeslider()
)
Aggregated Proportional change
Paper figure: Per Species Proportional change
LS0tCnRpdGxlOiAiU3BhdGlhbCBBbmFseXNpcyIKYXV0aG9yOiAiSnVsaWFubyBQYWxhY2lvcyBBYnJhbnRlcyIKb3V0cHV0OgogICMgaHRtbF9kb2N1bWVudDoKICBodG1sX25vdGVib29rOgogICAgZmlnX3dpZHRoOiA2CiAgICBmaWdfaGVpZ2h0OiA0CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDYKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgdGhlbWU6IGRhcmtseQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KE15RnVuY3Rpb25zKQpNeUZ1bmN0aW9uczo6bXlfbGliKGMoImdnbWFwIiwic2YiLCJzdCIsInRpZHl2ZXJzZSIsInRvb2xzIiwicmVhZHIiLCJkYXRhLnRhYmxlIiwibWFwcyIsInZpcmlkaXMiLCJ3ZXNhbmRlcnNvbiIsImtuaXRyIiwia2FibGVFeHRyYSIsInBsb3RseSIsImdncmVwZWwiLCJnZ3NmbGFiZWwiLCJqYW5pdG9yIiwiaW50ZXJwIiwicm5hdHVyYWxlYXJ0aCIsInJlYWR4bCIsImNvd3Bsb3QiKSkKCiMgRml4IG5ldyB1cGRhdGVzIG9mIHNmIHBhY2thZ2UKc2Y6OnNmX3VzZV9zMih1c2VfczIgPSBGQUxTRSkKCgojIENyZWF0ZSBzcGVjaWZpYyBzdGF0ZSBwYWxsZXQgZnJvbSBvdXIgZnJpZW5kIFdlcyBBbmRlcnNzb24Kc3RhdGVfcGFsbGV0IDwtIGMod2VzX3BhbGV0dGUobiA9IDUsIG5hbWUgPSAiRGFyamVlbGluZzEiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlc19wYWxldHRlKG4gPSA1LCBuYW1lID0gIkRhcmplZWxpbmcyIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZXNfcGFsZXR0ZShuID0gMywgbmFtZSA9ICJSb3lhbDEiKQogICAgICAgICAgICAgICAgICApCgpgYGAKCiMgTWV0aG9kcwoKIyMgU3BhdGlhbCBkYXRhIHByZXBhcmF0aW9uCgojIyMgTG9hZCBkYXRhCgojIyMjIE1hcHMgZGF0YQoKV2UgdXNlIHRocmVlIGRpZmZlcmVudCBzaGFwZWZpbGVzIGZvciB0aGUgY29udGluZW50YWwgVS5TLiBsYW5kIG1hc3MsIHRoZSBTdGF0ZSB3YXRlcnMgb2YgbWFpbmUsIG5ldyBoYW1wc2hpcmUsIG1hc3NhY2h1c2V0cywgY29ubmVjdGljdXQsIHJob2RlIGlzbGFuZCwgbmV3IHlvcmssIG5ldyBqZXJzZXksIGRlbGF3YXJlLCBtYXJ5bGFuZCwgdmlyZ2luaWEsIG5vcnRoIGNhcm9saW5hIGFuZCB0aGUgTm9ydGggRWFzdCBFRVouIE1vcmVvdmVyLCB3ZSB1c2UgdGhlIE5PQUEgZGF0YXNldCBvZiBsYW5kaW5ncyBwZXIgcG9ydC4KCiMjIyMjIDEuLSBMYW5kIHNoYXBlZmlsZQoKQ292ZXJzIHRoZSBVUyBsYW5kIHRlcnJpdG9yeSBmb3IgdmlzdWFsaXphdGlvbi4gRGF0YSBwcm92aWRlZCBmcm9tIHRoZSBgbWFwYCBwYWNrYWdlLgoKCmBgYHtyIGxhbmRfc2YsIGV2YWwgPSBULCBlY2hvID0gVCwgcmVzdWx0cyA9ICdoaWRlJ30KClN0YXRlcyA8LSBjKCJtYWluZSIsICJuZXcgaGFtcHNoaXJlIiwgIm1hc3NhY2h1c2V0dHMiLCAiY29ubmVjdGljdXQiLCAicmhvZGUgaXNsYW5kIiwgIm5ldyB5b3JrIiwgIm5ldyBqZXJzZXkiLCAiZGVsYXdhcmUiLCAibWFyeWxhbmQiLCAidmlyZ2luaWEiLCAibm9ydGggY2Fyb2xpbmEiKSAKCiMgLS0tLS0tLS0tLS0tLS0gIwojIFVTIFN0YXRlIE1hcCAobGFuZCkKIyAtLS0tLS0tLS0tLS0tLSAjCgpsYW5kX3NmIDwtIHN0X2FzX3NmKG1hcCgic3RhdGUiLCBwbG90ID0gRkFMU0UsIGZpbGwgPSBUUlVFKSkgJT4lIAogIGZpbHRlcihJRCAlaW4lIFN0YXRlcykgJT4lIAogIG11dGF0ZShhYnJldiA9IGMoIkNUIiwiREUiLCJNRSIsIk1EIiwiTUEiLCJOSCIsIk5KIiwiTlkiLCJOQyIsIlJJIiwiVkEiKSwKICAgICAgICAgc3RhdGUgPSBzdHJfdG9fc2VudGVuY2UoSUQpCiAgICAgICAgICkKCiMgVmlzdWFsIGV4cGxvcmF0aW9uIChvLmshICkKZ2dwbG90KGxhbmRfc2YpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gc3RhdGUpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgdGhlbWVfZGFyaygpCiAgICAgICAgICAKCmBgYAoKIyMjIyMgIDIuLSBFRVogc2hhcGVmaWxlCgpVc2VkIHRoZSAqU2VhIEFyb3VuZCBVcyogc2hhcGVmbGUgdXBkYXRlZCB0byBKdW5lIDIwMTYuCgpgYGB7ciBlZXpfc2YsIGV2YWwgPSBULCBlY2hvID0gVH0KCiMgVVMgRUVaIG1hcApwYXRoX3dvcmxkIDwtIG15X3BhdGgoIkciLCBleHRyYV9wYXRoID0gIlNwYXRpYWwvU0FVL1NBVV9TaGFwZWZpbGUiLCBuYW1lID0gIlNBVUVFWl9KdWx5MjAxNS5zaHAiKQoKIyBMb2FkIGl0IQplZXpfc2YgPC0gc3RfcmVhZChwYXRoX3dvcmxkKSAlPiUKICByZW5hbWUoZWV6X25hbWUgPSBOYW1lKSAlPiUKICBzdF90cmFuc2Zvcm0oY3JzID0gNDMyNikgJT4lICMgNDMyNgogIGZpbHRlcihlZXpfbmFtZSA9PSAiVVNBIChFYXN0IENvYXN0KSIpICU+JQogIHN0X3NpbXBsaWZ5KHByZXNlcnZlVG9wb2xvZ3kgPSBUUlVFLCBkVG9sZXJhbmNlID0gMC4xKSAjMC4xIGZvciBwYXBlcgoKIyBWaXN1YWwgZXhwbG9yYXRpb24gKG8uayEgKQpnZ3Bsb3QoZWV6X3NmKSArCiAgZ2VvbV9zZigpICsKICB0aGVtZV9kYXJrKCkKCmBgYAoKIyMjIyMgIDMuLSAgU3RhdGUgd2F0ZXJzCgpDb3ZlcnMgdGhlIHN0YXRlIHdhdGVycyBvZiB0aGUgTkUgVVMgc3RhdGVzLiBEYXRhIGZyb20gW2RhdGEuZ292XShodHRwczovL2NhdGFsb2cuZGF0YS5nb3YvZGF0YXNldC9mZWRlcmFsLWFuZC1zdGF0ZS13YXRlcnMpLiAgCgoqTGljZW5zZTogTm8gbGljZW5zZSBpbmZvcm1hdGlvbiB3YXMgcHJvdmlkZWQuIElmIHRoaXMgd29yayB3YXMgcHJlcGFyZWQgYnkgYW4gb2ZmaWNlciBvciBlbXBsb3llZSBvZiB0aGUgVW5pdGVkIFN0YXRlcyBnb3Zlcm5tZW50IGFzIHBhcnQgb2YgdGhhdCBwZXJzb24ncyBvZmZpY2lhbCBkdXRpZXMgaXQgaXMgY29uc2lkZXJlZCBhIFUuUy4gR292ZXJubWVudCBXb3JrLioKCmBgYHtyIHN0YXRlX3NmLCBldmFsID0gVCwgZWNobyA9IFR9CgoKc3RhdGVfc2YgPC0gIHN0X3JlYWQoIn4vT25lRHJpdmUgLSBVVy1NYWRpc29uL0ZlZGVyYWxBbmRTdGF0ZVdhdGVycy9GZWRlcmFsQW5kU3RhdGVXYXRlcnMuZ2RiIikgJT4lCiAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgCiAgbXV0YXRlKGp1cmlzZGljdGkgPSBzdHJfdG9fbG93ZXIoanVyaXNkaWN0aSkpICU+JSAKICBmaWx0ZXIoanVyaXNkaWN0aSAlaW4lIFN0YXRlcykgJT4lIAogIG11dGF0ZShzdGF0ZSA9IHN0cl90b19zZW50ZW5jZShqdXJpc2RpY3RpKSkgJT4lIAogIHN0X3RyYW5zZm9ybShjcnMgPSA0MzI2KSAlPiUgICAjIGZvciBtYXRjaGluZyBwcm9qZWN0aW9ucwogIHN0X3NpbXBsaWZ5KHByZXNlcnZlVG9wb2xvZ3kgPSBUUlVFLCBkVG9sZXJhbmNlID0gMTAwMDApICMwLjEgZm9yIHBhcGVyCgoKIyBWaXN1YWwgZXhwbG9yYXRpb24gKG8uayEgKQpnZ3Bsb3Qoc3RhdGVfc2YpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gc3RhdGUpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgdGhlbWVfZGFyaygpCgpgYGAKCiMjIyMjIDQuLSBGaXNoaW5nIHBvcnRzCgojIyMjIyMgNC4xIE5PQUEncyBkYXRhCgpEYXRhc2V0IHByb3ZpZGVyOiBKb2UgTXllcnMgSm9zZXBoLk15ZXJzQGFjY3NwLm9yZyBOT0FBCgpOb24tY29uZmlkZW50aWFsIGRhdGFzZXQgY29udGFpbmluZyBhbm51YWwgbGFuZGluZ3MvdmFsdWUgc3VtbWFyaWVzIGJ5IHBvcnQgZm9yIGJsYWNrIHNlYSBiYXNzLCBzY3VwIGFuZCBzdW1tZXIgZmxvdW5kZXIsIGZyb20gTkMtTUUgZm9yIDE5NzAtMjAyMC4gCgpJbiBvcmRlciB0byBtYWtlIHRoZSByZXBvcnQgbm9uLWNvbmZpZGVudGlhbCwgSSBhbSBkaXNwbGF5aW5nIGFzIG11Y2ggb2YgdGhlIHBvcnQtbGV2ZWwgc3VtbWFyeSBkYXRhIGFzIEkgY2FuIOKAkyBhbmQgZm9yIGNhc2VzIHdoZXJlIHRoZSBwb3J0LWxldmVsIHdhcyBjb25maWRlbnRpYWwsIEkgaGF2ZSBmaXJzdCBhdHRlbXB0ZWQgdG8gcm9sbC11cCBhbnkgY29uZmlkZW50aWFsIHBvcnQtbGV2ZWwgc3VtbWFyaWVzIGludG8gc3RhdGUtbGV2ZWwgc3VtbWFyaWVzIHdpdGhpbiB0aGUgc2FtZSB5ZWFyLiAgSWYgdGhvc2Ugc3RhdGUtbGV2ZWwgc3VtbWFyaWVzIGNvbnRpbnVlIHRvIGJlIGNvbmZpZGVudGlhbCwgSSBoYXZlIGZ1cnRoZXIgcm9sbGVkLXVwIHRob3NlIGNvbmZpZGVudGlhbCBwb3J0cyBhY3Jvc3Mgc3RhdGVzIGludG8gYSBjb2FzdC1sZXZlbCBzdW1tYXJ5LiAgRXZlbiBhdCB0aGUgY29hc3QgbGV2ZWwsIHRoZXJlIHdlcmUgc2V2ZXJhbCBjYXNlcyB3aGVyZSBub3QgZW5vdWdoIGNvbmZpZGVudGlhbCBwb3J0cyBjb3VsZCBiZSBjb21iaW5lZCB0byBwcm9kdWNlIGEgbm9uLWNvbmZpZGVudGlhbCBzdW1tYXJ5IOKAkyBhbmQgc28gZm9yIHRob3NlIHJvd3MgaXQgd2FzIG5lY2Vzc2FyeSB0byByZWRhY3QgdGhlIGZpbmFsIGxhbmRpbmdzL3ZhbHVlIGRhdGEuICBGb3J0dW5hdGVseSwgdGhpcyBvbmx5IGFtb3VudHMgdG8gbGVzcyB0aGFuIDAuNSUgb2YgdGhlIHRvdGFsIGxhbmRpbmdzIGRhdGEgKGNoYXJhY3Rlcml6ZWQgaW4gdGhlIOKAnFBpdm90IGJ5IENvbmZpZGVudGlhbGl0eeKAnSB0YWIgb2YgdGhlIHNwcmVhZHNoZWV0KS4KCgoqTGljZW5zZT8/Py4qCgpgYGB7cn0KIyBOT0FBIERBVEEKCnBvcnRzX3BhdGggPC0gbXlfcGF0aCgiRCIsIk5PQUEiLCBuYW1lID0gIlBhbGFjaW9zSiAtIEJTQiwgU0Zsb3VuZGVyLCBTY3VwIGJ5IFBvcnQgMTk3MC0yMDIwIC0gMjAyMS4xMC4yNS54bHN4IikKCgojIExvYWQgcG9ydHMKcG9ydHNfZGF0YSA8LSByZWFkX2V4Y2VsKHBvcnRzX3BhdGgsc2hlZXQgPSAyKSAlPiUgCiAgY2xlYW5fbmFtZXMoKSAlPiUKICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLAogICAgICAgICAgICB+IHN0cl90b19sb3dlciguKQogICkgJT4lIAogIG11dGF0ZSgKICAgIHNwZWNpZXNfbmFtZSA9IGlmZWxzZShzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCJibGFjayIpLCJibGFjayBzZWEgYmFzcyIsCiAgICAgICAgICAgICAgICAgaWZlbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsInN1bW1lciIpLCJzdW1tZXIgZmxvdW5kZXIiLAogICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSkKICAgICksCiAgICB0b3RhbF9saXZlX3BvdW5kcyA9IGFzLm51bWVyaWModG90YWxfbGl2ZV9wb3VuZHMpLAogICAgdG90YWxfdmFsdWUgPSBhcy5udW1lcmljKHRvdGFsX3ZhbHVlKQogICkgJT4lIAogIGZpbHRlcigKICAgICFwb3J0X25hbWUgJWluJSBjKCIqKnJvbGwtdXAgdG8gc3RhdGUtd2lkZSoqIiwiKipyb2xsLXVwIHRvIGNvYXN0LXdpZGUqKiIsInVua25vd24iKQogICkKYGBgCgoKIyMjIyMjIDQuMS4xIFRvcCBwb3J0cwoKYGBge3J9CiMgR2V0IG51bWJlciBvZiBwb3J0cyBpbiB0aGUgTk9BQSBkYXRhYmFzZQpvdmVyYWxsX3BvcnRfZGF0YSA8LSBwb3J0c19kYXRhICU+JQogIGZpbHRlcih5ZWFyID49IDIwMTAgJiB5ZWFyIDw9IDIwMTkpICU+JSAKICBncm91cF9ieShzcGVjaWVzX25hbWUscG9ydF9uYW1lLHN0YXRlX3Bvc3RhbCkgJT4lIAogIHN1bW1hcmlzZSgKICAgIHllYXJfdG9uID0gc3VtKHRvdGFsX2xpdmVfcG91bmRzKSwKICAgIHllYXJfdmFsdWUgPSBzdW0odG90YWxfdmFsdWUpCiAgKSAKCgp0b3BfcG9ydHMgPC0gYmluZF9yb3dzKAogICMgNzV0aCBwZXJjZW50aWxlIHVzZWQgaW4gcHJvamVjdAogIG92ZXJhbGxfcG9ydF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNwZWNpZXNfbmFtZSkgJT4lIAogICAgdG9wX2ZyYWMoMC4yNSx5ZWFyX3RvbikgJT4lICAjIHRvcCA3NQogICAgbXV0YXRlKHRyZXNoID0gIjc1dGgiKSwKICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAjIEZvciBzZW5zaXRpdml0eSB2YWx1ZXMKICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAjIDk1JQogIG92ZXJhbGxfcG9ydF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNwZWNpZXNfbmFtZSkgJT4lIAogICAgdG9wX2ZyYWMoMC41LHllYXJfdG9uKSAlPiUgIAogICAgbXV0YXRlKHRyZXNoID0gIjk1dGgiKSwKICAjIDg1JQogIG92ZXJhbGxfcG9ydF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNwZWNpZXNfbmFtZSkgJT4lIAogICAgdG9wX2ZyYWMoMC4xNSx5ZWFyX3RvbikgJT4lIAogICAgbXV0YXRlKHRyZXNoID0gIjg1dGgiKSwKICAjIDY1JQogIG92ZXJhbGxfcG9ydF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNwZWNpZXNfbmFtZSkgJT4lIAogICAgdG9wX2ZyYWMoMC4zNSx5ZWFyX3RvbikgJT4lICAjIHRvcCA3NQogICAgbXV0YXRlKHRyZXNoID0gIjY1dGgiKSwKICAjIDUwJQogIG92ZXJhbGxfcG9ydF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNwZWNpZXNfbmFtZSkgJT4lIAogICAgdG9wX2ZyYWMoMC41LHllYXJfdG9uKSAlPiUgICMgdG9wIDc1CiAgICBtdXRhdGUodHJlc2ggPSAiNTB0aCIpCikKICAKYGBgCgojIyMjIyMgNC4xLjIgUG9ydHMgY29vcmRpbmF0ZXMKCgpgYGB7ciBzYXJhaHNfd29yZF9kYXRhfQogCm5vYWFfcG9ydHMgPC0gZGF0YS50YWJsZSgKICBwb3J0ID1zdHJfdG9fc2VudGVuY2UoYygKICAgICJQT0lOVCBKVURJVEgsIFJJIiwgIzQxLjM1OTkwNzkxNDU1MzU3NCwtNzEuNDgzMjMyNTA4NzIxODcsCiAgICAiQkVBVUZPUlQsIE5DIiwgIzM0LjcxMzg4Nzk2NTQwNTQsLTc2LjY2MjM5NjMwMTE3OTIxLAogICAgIkhBTVBUT04sIFZBIiwgIzM2Ljk4NjAwMzY2NzczMzI3LCAtNzYuMzUwMzgzMDY4NTk1NDUsCiAgICAiUE9JTlQgUExFQVNBTlQsIE5KIiwgIzQwLjA4MzUxODQ3Njc1MTAyLC03My45OTE5MDA5NDExMDY3OSwKICAgICJORVdQT1JUIE5FV1MsIFZBIiwgIzM3LjAwOTMzOTE5Mjk1MTgzLCAtNzYuNDg1NjU4NjI2MTMxNjgsCiAgICAiQkVMRk9SRCwgTkoiLCAjIDQwLjQzOTE4Nzg0NzM0MDI0LCAtNzQuMDc2MzA1NDg5OTQ2MgogICAgIk1PTlRBVUssIE5ZIiwgIzQxLjA3MzQyMjYyODY4MDM4LCAtNzEuOTM1ODU4MzYwODg4MTMKICAgICJIT0JVQ0tFTiwgTkMiLCAjMzQuOTQ4NDQ1Njc5ODIzODQsIC03Ni43NDMzMzQxOTU2MDQyNQogICAgIldBTkNIRVNFLCBOQyIsICMzNS44MzUyNDk4NDU1MDMzNCwgLTc1LjYxMTIxNjcxNzIyOTIxCiAgICAiTkVXIEJFREZPUkQsIE1BIiwgIyA0MS42MzA0OTQwNTIzMjYzMDYsIC03MC45MTU4MDY2OTEzNDA1NQogICAgIkNBUEUgTUFZLCBOSiIsICMgMzguOTQ5Nzk3MTkxMjY1MDgsIC03NC45MDI4MDk0NDc5MDQ2MwogICAgIk9SSUVOVEFMLCBOQyIsICMgMzUuMDEzNTcxMDg0MzczMTI2LCAtNzYuNjY3OTMxMTQzMzM3MDQKICAgICJDSElOQ09URUFHVUUsIFZBIiwgIyAzNy45MTc4ODA5NDA3MDIwNCwgLTc1LjM1OTQ3NTgwNDc4MjE5CiAgICAiRU5HRUxIQVJELCBOQyIsICMgMzUuMjYyOTI5MjQzMTE4Nzc2LCAtNzYuMDg2ODA0NTI2NzA1MDgKICAgICJTVE9OSU5HVE9OLCBDVCIsICMgNDEuMzI3MjgyMjA0NDg0MDM1LCAtNzEuOTIyMzcyMTM1OTI1MQogICAgIkxPTkcgQkVBQ0gvQkFSTkVHQVQgTElHSFQsIE5KIiwgIzM5Ljc1Mjg1NTkyOTkwMDQ4NCwgLTc0LjExMzI5MzEwMTE1OTAyCiAgICAiT0NFQU4gQ0lUWSBoYXJib3IsIE1EIiwgIzM4LjM4MDI5MjIwMDQ4NTksIC03NS4wNTA4OTczNjkyMDMxOAogICAgIyBNYW51YWxseSBpbmNsdWRlZCB0aGVzZSBwb3J0cyBhcyB0b3AgU3RhdGUgcG9ydHMgZnJvbSBOT0FBCiAgICAiSW5kaWFuIHJpdmVyLCBERSIsCiAgICAiUG9ydGxhbmQsIE1FIiwgIzQzLjY2MzQ0Nzk0NzI4OTkyLCAtNzAuMjI5Mzc1NTQzNzg4ODUKICAgICJQb3J0c21vdXRoLCBOSCIsICM0My4wNTMzNDY5NDIwMzk1MywgLTcwLjcxMjY3NjA4MzM3MTQKICAgICMgTW9yZSBwb3J0cwogICAgIkNoaW5jb3RlYWd1ZSwgVkEiLCAjIDM3Ljk0Mjk1ODk2MzAyNDY1LCAtNzUuMzg0MTU2Njg1Nzk4ODcKICAgICJzZWEgaXNsZSBjaXR5LE5KICIsICMgMzkuMTQ5MTI2NTYzMjM4NTQsIC03NC42ODc5NzIwMjg0Nzg3MQogICAgImxld2VzLCBERSwgIiwgIyAzOC43ODk0MzY0MDk5MDU0MiwgLTc1LjA2MzQzNjkyNjEwODUxCiAgICAidmlyZ2luaWEgYmVhY2gsIFZBIiwgIyAzNi44NTkzNDMzODU3MjI1MDQsIC03NS45NDMyODM5ODE0MDA2NQogICAgImhhbXB0b24gYmF5cywgbnkiLCAjNDAuODQyMjkwNDAxODkyMDQsIC03Mi41MDk4NzU0NDA0MDk5OQogICAgIm1hdHRpdHVjaywgbnkiLCAjIDQxLjA1MzQyODM2MTkyMjkzLCAtNzIuNTk4OTkyMTQyNTgyNjkKICAgICJsaXR0bGUgY29tcHRvbiwgcmkiLCAjIDQxLjQ3NjUxMDM0NjEyMTMsIC03MS4xOTQ3NDY0MTU3OTEwNwogICAgIm5ldyBsb25kb24sIENUIiwgIzQxLjM0MTU3NzIwNzQ2NzkxNCwgLTcyLjA4Mjk2OTcxMDY0ODkKICAgICJhbWFnYW5zZXR0LCBueSIsICMgNDAuOTYxNzMwMDg2MzM1NjksIC03Mi4xMTg3OTMwNjc0MDc5OAogICAgImJhcm5lZ2F0IGxpZ2h0LCBuaiIsICMzOS43NTI5MTE1MjY2MjM4MywgLTc0LjA5OTI3ODMxODY4MzA4CiAgICAiY2hhdGhhbSAoY2Vuc3VzIG5hbWUgZm9yIGNoYXRoYW0gY2VudGVyKSwgTUEiLCAjIDQxLjY1ODY5NTQyMTEyMjQ3NCwgLTY5Ljk1NDY2NDUyNTU2NDQ4CiAgICAiZGVubmlzLCBtYSIsICM0MS42NTEyMTAzNzI2Mzg3MywgLTcwLjEzMTkzNjYzNzk4NTA5CiAgICAiZmFsbW91dGggKGNlbnN1cyBuYW1lIGZvciBmYWxtb3V0aCBjZW50ZXIpLCBtYSIsICM0MS41Mzk1NjMyNzE0NjUyNiwgLTcwLjYwMDAxMzQwNzA5NjY1LAogICAgImZyZWVwb3J0LCBueSIsICM0MC42MjI0MjM4NzQ3MzEwOSwgLTczLjU5MTYyNTA5NDAyMjA4CiAgICAibmFudHVja2V0IChjZW5zdXMgbmFtZSBmb3IgbmFudHVja2V0IGNlbnRlciksIE1BIiwgIzQxLjI2NjE2MDg4MjEwOTg1LCAtNjkuOTU2MTcyNzcyNTc5ODUKICAgICJuZXdwb3J0LCBSSSIsCiAgICAicG9pbnQgbG9va291dCwgbnkiLCAjNDAuNTg3NjQ2MTM0OTU1ODc1LCAtNzMuNTc2Mzc0ODUxMjkyNwogICAgInNoaW5uZWNvY2sgaW5kaWFuIHJlc2VydmF0aW9uLCBueSIsICM0MC44NjU4NzM5ODM5Njg3NTQsIC03Mi40NDIwOTI5MTcyMDE4CiAgICAid2VzdHBvcnQsIG1hIgogICkpLAogIGxhdCA9IGMoCiAgICA0MS4zNTk5MDc5MTQ1NTM1NzQsCiAgICAzNC43MTM4ODc5NjU0MDU0LAogICAgMzYuOTg2MDAzNjY3NzMzMjcsIAogICAgNDAuMDgzNTE4NDc2NzUxMDIsCiAgICAzNy4wMDkzMzkxOTI5NTE4MywgCiAgICA0MC40MzkxODc4NDczNDAyNCwgCiAgICA0MS4wNzM0MjI2Mjg2ODAzOCwKICAgIDM0Ljk0ODQ0NTY3OTgyMzg0LCAKICAgIDM1LjgzNTI0OTg0NTUwMzM0LAogICAgNDEuNjMwNDk0MDUyMzI2MzA2LAogICAgMzguOTQ5Nzk3MTkxMjY1MDgsCiAgICAzNS4wMTM1NzEwODQzNzMxMjYsCiAgICAzNy45MTc4ODA5NDA3MDIwNCwgCiAgICAzNS4yNjI5MjkyNDMxMTg3NzYsIAogICAgNDEuMzI3MjgyMjA0NDg0MDM1LCAKICAgIDM5Ljc1Mjg1NTkyOTkwMDQ4NCwgCiAgICAzOC4zODAyOTIyMDA0ODU5LAogICAgMzguNjIxMTM1OTM0MDM3NDYsCiAgICA0My42NjM0NDc5NDcyODk5MiwKICAgIDQzLjA1MzM0Njk0MjAzOTUzLAogICAgMzcuOTQyOTU4OTYzMDI0NjUsCiAgICAzOS4xNDkxMjY1NjMyMzg1NCwKICAgIDM4Ljc4OTQzNjQwOTkwNTQyLAogICAgMzYuODU5MzQzMzg1NzIyNTA0LAogICAgNDAuODQyMjkwNDAxODkyMDQsCiAgICA0MS4wNTM0MjgzNjE5MjI5MywKICAgIDQxLjQ3NjUxMDM0NjEyMTMsIAogICAgNDEuMzQxNTc3MjA3NDY3OTE0LAogICAgNDAuOTYxNzMwMDg2MzM1NjksIAogICAgMzkuNzUyOTExNTI2NjIzODMsIAogICAgNDEuNjU4Njk1NDIxMTIyNDc0LAogICAgNDEuNjUxMjEwMzcyNjM4NzMsIAogICAgNDEuNTM5NTYzMjcxNDY1MjYsIAogICAgNDAuNjIyNDIzODc0NzMxMDksCiAgICA0MS4yNjYxNjA4ODIxMDk4NSwgCiAgICA0MS40ODU1MTQzNDY2ODM5NTYsCiAgICA0MC41ODc2NDYxMzQ5NTU4NzUsCiAgICA0MC44NjU4NzM5ODM5Njg3NTQsCiAgICA0MS40OTI2Nzg3NTc0Njg3MwogICksCiAgbG9uID0gYygKICAgIC03MS40ODMyMzI1MDg3MjE4NywKICAgIC03Ni42NjIzOTYzMDExNzkyMSwKICAgIC03Ni4zNTAzODMwNjg1OTU0NSwKICAgIC03My45OTE5MDA5NDExMDY3OSwKICAgIC03Ni40ODU2NTg2MjYxMzE2OCwKICAgIC03NC4wNzYzMDU0ODk5NDYyLAogICAgLTcxLjkzNTg1ODM2MDg4ODEzLAogICAgLTc2Ljc0MzMzNDE5NTYwNDI1LAogICAgLTc1LjYxMTIxNjcxNzIyOTIxLAogICAgLTcwLjkxNTgwNjY5MTM0MDU1LAogICAgLTc0LjkwMjgwOTQ0NzkwNDYzLAogICAgLTc2LjY2NzkzMTE0MzMzNzA0LAogICAgLTc1LjM1OTQ3NTgwNDc4MjE5LAogICAgLTc2LjA4NjgwNDUyNjcwNTA4LAogICAgLTcxLjkyMjM3MjEzNTkyNTEsCiAgICAtNzQuMTEzMjkzMTAxMTU5MDIsCiAgICAtNzUuMDUwODk3MzY5MjAzMTgsCiAgICAtNzUuMDYzOTcwMjE3MTgzNDUsCiAgICAtNzAuMjI5Mzc1NTQzNzg4ODUsCiAgICAtNzAuNzEyNjc2MDgzMzcxNCwKICAgIC03NS4zODQxNTY2ODU3OTg4NywKICAgIC03NC42ODc5NzIwMjg0Nzg3MSwKICAgIC03NS4wNjM0MzY5MjYxMDg1MSwKICAgIC03NS45NDMyODM5ODE0MDA2NSwKICAgIC03Mi41MDk4NzU0NDA0MDk5OSwKICAgIC03Mi41OTg5OTIxNDI1ODI2OSwKICAgIC03MS4xOTQ3NDY0MTU3OTEwNywgCiAgICAtNzIuMDgyOTY5NzEwNjQ4OSwKICAgIC03Mi4xMTg3OTMwNjc0MDc5OCwKICAgIC03NC4wOTkyNzgzMTg2ODMwOCwKICAgICAtNjkuOTU0NjY0NTI1NTY0NDgsCiAgICAtNzAuMTMxOTM2NjM3OTg1MDksCiAgICAtNzAuNjAwMDEzNDA3MDk2NjUsCiAgICAgLTczLjU5MTYyNTA5NDAyMjA4LAogICAgLTY5Ljk1NjE3Mjc3MjU3OTg1LAogICAgIC03MS4zMjI2MzMyNjk3NTEyMiwKICAgICAtNzMuNTc2Mzc0ODUxMjkyNywKICAgICAtNzIuNDQyMDkyOTE3MjAxOCwKICAgIC03MS4wNTU1MTM0MjM5MjAzOQogICkKKSAlPiUgCiAgc2VwYXJhdGUocG9ydCwgaW50byA9IGMoInBvcnRfbmFtZSIsInN0YXRlX3Bvc3RhbCIpLCBzZXAgPSAnLCcpICU+JSAKICBtdXRhdGUocG9ydF9uYW1lID0gc3RyX3RvX2xvd2VyKHBvcnRfbmFtZSksCiAgICAgICAgIHN0YXRlX3Bvc3RhbCA9IHN0cl9zcXVpc2goc3RhdGVfcG9zdGFsKSkKICAKIyBJbmNsdWRlIGNvb3JkaW5hdGVzCm5vYWFfcG9ydHNfY29tcGxldGUgPC0gdG9wX3BvcnRzICU+JSAKICBsZWZ0X2pvaW4obm9hYV9wb3J0cywKICAgICAgICAgICAgIGJ5ID0gYygicG9ydF9uYW1lIiwgInN0YXRlX3Bvc3RhbCIpKSAlPiUgCiAgbXV0YXRlKAogICAgc3RhdGVfcG9zdGFsID0gc3RyX3RvX3VwcGVyKHN0YXRlX3Bvc3RhbCkKICApCiAgCiMgQ2hlY2sgZm9yIG1pc3NpbmcgcG9ydHMKbm9hYV9wb3J0c19jb21wbGV0ZSAlPiUgCiAgZmlsdGVyKHRyZXNoID09ICI3NXRoIiwKICAgIGlzLm5hKGxhdCkpICU+JSAKICBncm91cF9ieShwb3J0X25hbWUsc3RhdGVfcG9zdGFsKSAlPiUgCiAgc3VtbWFyaXNlKG4oKSkgJT4lIAogIFZpZXcoKQoKIyBTYXZlIGRhdGEgZm9yIGZ1dHVyZSBhbmFseXNpcwojIHdyaXRlX2Nzdihub2FhX3BvcnRzX2NvbXBsZXRlLAojICAgICAgICAgICBteV9wYXRoKCJEIiwiUGFydGlhbCIsIG5hbWUgPSAidG9wX3BvcnRzLmNzdiIpCiMgICAgICAgICAgICkKCm5vYWFfcG9ydHNfY29tcGxldGUKCmBgYAoKIyMjIyMjIDQuMS4xIFZpc3VhbGl6YXRpb24KCgpgYGB7cn0KCm5vYWFfcG9ydHNfY29tcGxldGUgJT4lIAogIGZpbHRlcih0cmVzaCA9PSAiNzV0aCIpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludCgKICAgIGFlcygKICAgICAgeCA9IGxvbiwKICAgICAgeSA9IGxhdCwKICAgICAgc2hhcGUgPSBzcGVjaWVzX25hbWUsIAogICAgICBjb2xvciA9IHNwZWNpZXNfbmFtZQogICAgKSwKICAgIHNpemUgPSA1LAogICAgYWxwaGEgPSAwLjUKICApCgpgYGAKCgo8IS0tIFRoaXMgaXMgaG93IGFsbCB0aGUgc2hhcGVmaWxlcyBsb29rIGxpa2UgdG9nZXRoZXIgLS0+CgoKYGBge3IgYWxsX3NmLCBldmFsID0gVCwgZWNobyA9IFR9CgojIFZpc3VhbCBleHBsb3JhdGlvbiBvZiBhbGwgdG9nZXRoZXIgKG8uayEgKQpnZ3Bsb3QoKSArCiAgZ2VvbV9zZihkYXRhID0gZWV6X3NmLCBhZXMoKSkgKwogIGdlb21fc2YoZGF0YSA9IGxhbmRfc2YsIGFlcyhmaWxsID0gc3RhdGUpLCBhbHBoYSA9IDAuMykgKwogIGdlb21fc2YoZGF0YSA9IHN0YXRlX3NmLCBhZXMoY29sb3IgPSBzdGF0ZSksIGZpbGwgPSBOQSkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldChub2FhX3BvcnRzX2NvbXBsZXRlLCB0cmVzaCA9PSAiNzV0aCIpLCBhZXMoeCA9IGxvbiwgeSA9IGxhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlID0gc3BlY2llc19uYW1lKSwgc2l6ZSA9IDMsIGFscGhhID0gMC43KSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogIHRoZW1lX2RhcmsoKSArCiAgY29vcmRfc2YoeWxpbSA9IGMoMzMsNDgpKQoKYGBgCgoKIyMjIENyZWF0ZSBiYXNlIHNoYXBlZmlsZSBmb3IgY29tcHV0YXRpb24KCkFzIGEgZmlyc3Qgc3RlcCB3ZSBuZWVkIHRvIGRpdmlkZSB0aGUgTkUgVVMgRUVaIGFtb25nIHRoZSBkaWZmZXJlbnQgc3RhdGVzLiBGb3IgdGhhdCwgd2UgZXhwYW5kZWQgYSBidWZmZXItcG9seWdvbiB0byB0aGUgMjAwIG5hdXRpY2FsIG1pbGVzIHRvIHRoZW4gZXN0aW1hdGUgdGhlIHBlcmNlbnRhZ2UgdGhhdCBlYWNoIGV4cGFuZGVkIHBvbHlnb24gb2NjdXBpZWQuIEZvciB0aGUgaW5pdGlhbCBidWZmZXIgcG9pbnQgd2UgdXNlZCB0d28gYXBwcm9hY2hlczsgc3RhdGUgd2F0ZXJzIGFuZCBVUyBwb3J0cy4gTm90ZSB0aGF0IGluIGFsbCBjYXNlcyB0aGVzZSBhcmVhcyBvdmVybGFwcGVkIGFuZCBwZXJjZW50YWdlcyBhY2NvdW50ZWQgZm9yIGl0LiBXZSBkaWQgdGhpcyBieSBmb2xsb3dpbmcgdGhlc2Ugc3RlcHM6CgotIDEuIEV4cGFuZCBzdGF0ZSB3YXRlcnMgLyBVUyBwb3J0cyB1c2luZyBhIGJ1ZmZlcgoKLSAyLiBHcmlkIHRoYXQgYnVmZmVyIG9uIGEgMC4zIHJlc29sdXRpb24KCi0gMy4gQ3JvcCB0aGUgYnVmZmVyIHRvIHRoZSBFRVoKCiMjIyMgMS4gRXhwYW5kIFNwYXRpYWwgcmVnaW9ucyAoYS5rLmEgIGJ1ZmZlcnMpCgojIyMjIyAxLjEgU3RhdGUgV2F0ZXJzCgpXZSBzZXQgYSBidWZmZXIgb2YgKjQxMDAwMCogbSAoNDEwIGttLCB+IDIyMSBubSkgdGhhdCBvdmVyc2hvb3RzIHRoZSBFRVogYSBiaXQsIGJ1dCBpcyBldmVudHVhbGx5IGNyb3BwZWQKCmBgYHtyIHN3X2J1ZmZlciwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKIyBCdWZmZXIgc3RhdGUgd2F0ZXJzCnN0YXRlX2JmID0gc3RfYnVmZmVyKHN0YXRlX3NmLCA0KSAlPiUgCiAgc3RfdHJhbnNmb3JtKDQzMjYpICU+JSAjIHRvIG1hdGNoIHNoYXBlCiAgc3Rfc2V0X2Nycyg0MzI2KQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwojIFRlc3RpbmcgYW5kIHZpc3VhbGl6aW5nIHRoZSBidWZmZXIgCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCnN0YXRlX2JmX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IHN0YXRlX3NmLCBhZXMoY29sb3IgPSBzdGF0ZSksIGZpbGwgPSBOQSkgKwogIGdlb21fc2YoZGF0YSA9IGVlel9zZiwgYWVzKCksIGZpbGwgPSBOQSkgKwogIGdlb21fc2YoZGF0YSA9IHN0YXRlX2JmLCBhZXMoY29sb3IgPSBzdGF0ZSksIGZpbGwgPSBOQSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpKwogIHRoZW1lX2RhcmsoKQojICAgCgojIGdnc2F2ZSgiLi4vUmVzdWx0cy9QYXJ0aWFsL3N0YXRlX3dhdGVyc19idWZmZXIucG5nIixzdGF0ZV9iZl9wbG90KQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKc3RhdGVfYmZfcGxvdAoKYGBgCgojIyMjIyAxLjEgVVMuIFBvcnRzCgpXZSBzZXQgYSBidWZmZXIgb2YgKjUqIGRlZyAoNTEwIGttLCB+IDIyMSBubSkgdGhhdCBvdmVyc2hvb3RzIHRoZSBFRVogYSBiaXQsIGJ1dCBpcyBldmVudHVhbGx5IGNyb3BwZWQKCmBgYHtyIGZwX2J1ZmZlciwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKCiNMb2FkIHRvcCBwb3J0IGRhdGEgCnBvcnRzX2RmIDwtIG15X3BhdGgoIkQiLCJQYXJ0aWFsIiwgInRvcF9wb3J0cy5jc3YiLCByZWFkID0gVCkgJT4lIAogIGZpbHRlcih0cmVzaCA9PSAiNzV0aCIpICU+JQogIGRpc3RpbmN0KHBvcnRfbmFtZSwgLmtlZXBfYWxsID0gVCkgIyBObyBuZWVkIGZvciBkdXBsaWNhdGlvbgoKcG9ydF9zZiA8LSBzdF9hc19zZihwb3J0c19kZiwKICAgICAgICAgICAgICAgICAgICBjb29yZHMgPWMoImxvbiIsImxhdCIpLAogICAgICAgICAgICAgICAgICAgIGNycyA9IDQzMjYpCgojIEJ1ZmZlciBzdGF0ZSB3YXRlcnMKcG9ydF9iZiA8LSBzdF9idWZmZXIocG9ydF9zZiwgNSkgJT4lICMgcG9ydAogIHN0X3RyYW5zZm9ybSg0MzI2KSAlPiUgIyB0byBtYXRjaCBzaGFwZQogIHN0X3NldF9jcnMoNDMyNikKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKIyBUZXN0aW5nIGFuZCB2aXN1YWxpemluZyB0aGUgYnVmZmVyIAojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgpnZ3Bsb3QoKSArCiAgZ2VvbV9zZihkYXRhID0gZWV6X3NmLCBhZXMoKSxmaWxsID0gTkEpICsKICBnZW9tX3NmKGRhdGEgPSBwb3J0X2JmLCBhZXMoKSwgZmlsbCA9IE5BKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkrCiAgdGhlbWVfZGFyaygpCgpgYGAKCgojIyMjIDIuIEV4cGFuZCBncmlkIHdpdGhpbiBidWZmZXIKCkhlcmUgd2UgZXhwYW5kIGEgZ3JpZCB3aXRoaW4gdGhlIGJ1ZmZlciBzbyB3ZSBjYW4gZXN0aW1hdGUgdGhlIHByb3BvcnRpb24gb2YgZWFjaCBzdGF0ZS4KCipOb3RlOiogRGFyayBncmV5IHNoYWRlZCBhcmVhIGlzIHRoZSBncmlkIGFuZCBpcyB0aGUgc2FtZSBmb3IgYm90aCBhcHByb2FjaGVzCgpgYGB7ciBncmlkX2luZGV4aW5nLCBldmFsID0gVCwgZWNobyA9IFQsIG1lc3NhZ2UgPSBGLCB3YXJuaW5nID0gRn0KCiMgQ3JlYXRlIGdyaWQgb2YgdGhlIHJlZ2lvbgpiYm94IDwtIGMoc3RfYmJveChzdGF0ZV9iZikpCgojIEV4cGFuZCB0aGUgZ3JpZApuZV9ncmlkIDwtIGV4cGFuZC5ncmlkKAogICAgbG9uID0gc2VxKGZyb20gPSBiYm94WyJ4bWluIl0sIHRvID0gYmJveFsieG1heCJdLCBieSA9IDAuMyksCiAgICBsYXQgPSBzZXEoZnJvbSA9IGJib3hbInltaW4iXSwgdG8gPSBiYm94WyJ5bWF4Il0sIGJ5ID0gMC4zKQopICU+JSAKICByb3dpZF90b19jb2x1bW4oImluZGV4IikKCiMgLS0tLS0tLS0tLS0gIwojIFtURVNUXSBQbG90IGFsbCBsYXllcnMKIyAtLS0tLS0tLS0tLSAjCgojIExvb2tzIGdvb2QKc3RhdGVfc2YgJT4lCiAgc3RfdHJhbnNmb3JtKDQzMjYpICU+JSAjIHRvIG1hdGNoIHNoYXBlCiAgc3Rfc2V0X2Nycyg0MzI2KSAlPiUKICAjIHN0X3NpbXBsaWZ5KHByZXNlcnZlVG9wb2xvZ3kgPSBUUlVFLCBkVG9sZXJhbmNlID0gMTAwMDApICU+JQogIGdncGxvdCgpICsKICBnZW9tX3NmKGFlcyhjb2xvciA9IHN0YXRlKSkrCiAgIyBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsIGFlcygpLGZpbGwgPU5BKSArCiAgIyBnZ3Bsb3QoKSsKICBnZW9tX3RpbGUoZGF0YSA9IG5lX2dyaWQsCiAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICB4ID0gbG9uLAogICAgICAgICAgICAgIHkgPSBsYXQKICAgICAgICAgICAgKSwKICAgICAgICAgICAgYWxwaGEgPSAwLjIKICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWVfZGFyaygpCgpgYGAKCiMjIyMjIDIuMSBDcmVhdGUgZ3JpZCBmb3IgaW50ZXJwb2xhdGlvbgoKYGBge3IgaW50ZXJfZ3JpZCwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKIyBDcm9wIGdyaWQgdG8gRUV6CmludGVyX2dyaWRfc2YgPC0gc3RfYXNfc2YobmVfZ3JpZCwKICAgICAgICAgICAgIGNvb3JkcyA9IGMoImxvbiIsICJsYXQiKSwKICAgICAgICAgICAgIGNycyA9IDQzMjYpICU+JSAKICBzdF9pbnRlcnNlY3Rpb24oZWV6X3NmKQoKaW50ZXJfZ3JpZF9kZiA8LSBhcy5kYXRhLmZyYW1lKGludGVyX2dyaWRfc2YpICU+JSAKICBzZWxlY3QoaW5kZXgpICU+JSAKICBsZWZ0X2pvaW4obmVfZ3JpZCkKCiMgU2F2ZSBncmlkIGZvciBmdXR1cmUgYW5hbHlzaXMKIyB3cml0ZV9jc3YoaW50ZXJfZ3JpZF9kZiwgcGFzdGUwKG15X3BhdGgoIlIiLCAiUGFydGlhbCIpLCJpbnRlcl9ncmlkX2RmLmNzdiIpKQoKCmdncGxvdChpbnRlcl9ncmlkX3NmKSArCiAgZ2VvbV9zZigpCgoKYGBgCgoKIyMjIyMgMi4xIE1lcmdlIGdyaWQgYW5kIGJ1ZmZlcnMKCk9uY2Ugd2UgaGF2ZSBhIGdyaWRkZWQgYXJlYSwgd2UgY29udmVydGVkIHRoZSBncmlkIHRvIGEgYHNmYCBzbyB3ZSBjYW4gbWVyZ2UgaXQgd2l0aCB0aGUgYnVmZmVyZWQgc3RhdGVzIGFuZCBwb3J0cyBhbmQgZmluYWxseSBmaWx0ZXIgb3V0IGV2ZXJ5dGhpbmcgb3V0c2lkZSB0aGUgc3RhdGVzIHBvbHlnb24KCiMjIyMjIyAyLjEuMSBTdGF0ZSBXYXRlcnMKCmBgYHtyIGdyaWRfc3dfYnVmX21lcmdlLCBldmFsID0gVCwgZWNobyA9IFQsIG1lc3NhZ2UgPSBGLCB3YXJuaW5nID0gRiwgZmlnLndpZHRoID0gMTB9CgojIC0tLS0tLS0tLS0tLS0tLS0gIwojIENvbnZlcnQgZ3JpZCB0byBzZgojIC0tLS0tLS0tLS0tLS0tLS0gIwpncmlkX3N3X3NmIDwtIHN0X2FzX3NmKG5lX2dyaWQsCiAgICAgICAgICAgICBjb29yZHMgPSBjKCJsb24iLCAibGF0IiksCiAgICAgICAgICAgICBjcnMgPSA0MzI2KSAlPiUgCiAgc3Rfam9pbihzdGF0ZV9iZikgJT4lIAogIGZpbHRlcighaXMubmEoc3RhdGUpKQoKIyBDcmVhdGUgZGF0YSBmcmFtZSBmb3IgZnV0dXJlIGNvbXB1dGF0aW9ucwojIE5vdGUsIHdpbGwgYmUgdXNlZCBpbiBuZXh0IGNodW5rCmdyaWRfc3dfYmZfZHQgPC0gYXMuZGF0YS5mcmFtZShncmlkX3N3X3NmKSAlPiUKICAgIHNlbGVjdChpbmRleCxzdGF0ZSkKICAgICMgZ3JvdXBfYnkoc3RhdGUpICU+JSAKICAgICMgc3VtbWFyaXNlKGxlbmd0aChpbmRleCkpCgoKIyAtLS0tLS0tLS0tLS0tLS0tICMKIyBbVEVTVF0gCiMgVmlzdWFsaXphdGlvbiBvZiBncmlkCiMgLS0tLS0tLS0tLS0tLS0tLSAjCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZSgKICAjIE92ZXJhbGwgKG92ZXJsYXBwaW5nKSBwb3NpdGlvbgogIGdncGxvdChncmlkX3N3X3NmKSArCiAgICBnZW9tX3NmKGRhdGEgPSBzdGF0ZV9zZiwgYWVzKCksIGZpbGwgPSBOQSkgKwogICAgZ2VvbV9zZihhZXMoY29sb3IgPSBzdGF0ZSksIGFscGhhID0gMC4zKSArCiAgICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsIGFlcygpLGZpbGwgPU5BKSArIAogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgdGhlbWVfZGFyaygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICIiKSwKICAjIFNob3dpbmcgZWFjaCBzdGF0ZSBzZXBhcmF0bGV5CiAgZ2dwbG90KCkgKwogICAgZ2VvbV9zZihkYXRhID0gZ3JpZF9zd19zZiwgYWVzKGNvbG9yID0gc3RhdGUpLHNpemUgPSAwLjEsIGFscGhhID0gMC41KSArCiAgICBmYWNldF93cmFwKH5zdGF0ZSkgKwogICAgdGhlbWVfZGFyaygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSwKICBucm93ID0gMSkgCgpgYGAKCiMjIyMjIyAyLjEuMSBGaXNoaW5nIFBvcnRzCgpgYGB7ciBncmlkX2ZwX2J1Zl9tZXJnZSwgZXZhbCA9IFQsIGVjaG8gPSBULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEYsIGZpZy53aWR0aCA9IDEwfQoKIyAtLS0tLS0tLS0tLS0tLS0tICMKIyBDb252ZXJ0IGdyaWQgdG8gc2YgCiMgLS0tLS0tLS0tLS0tLS0tLSAjCmdyaWRfZnBfc2YgPC0gc3RfYXNfc2YobmVfZ3JpZCwKICAgICAgICAgICAgIGNvb3JkcyA9IGMoImxvbiIsICJsYXQiKSwKICAgICAgICAgICAgIGNycyA9IDQzMjYpICU+JSAKICBzdF9qb2luKHBvcnRfYmYpICU+JSAjIGpvaW4gdG8gcG9ydCBzZgogIGZpbHRlcighaXMubmEocG9ydF9uYW1lKSkgJT4lCiAgZGlzdGluY3QoaW5kZXgscG9ydF9uYW1lLCAua2VlcF9hbGwgPSBUUlVFKSAjcmVtb3ZlcyBsaWtlIDQwMEsgb3ZlcmxhcHBpbmcgcm93cwoKIyBDcmVhdGUgZGF0YSBmcmFtZSBmb3IgZnV0dXJlIGNvbXB1dGF0aW9ucwojIE5vdGUsIHdpbGwgYmUgdXNlZCBpbiBuZXh0IGNodW5rCmdyaWRfZnBfYmZfZHQgPC0gYXMuZGF0YS5mcmFtZShncmlkX2ZwX3NmKSAlPiUKICAgIHNlbGVjdChpbmRleCxwb3J0X25hbWUsc3BlY2llc19uYW1lKQoKIyAtLS0tLS0tLS0tLS0tLS0tICMKIyBbVEVTVF0gCiMgVmlzdWFsaXphdGlvbiBvZiBncmlkCiMgLS0tLS0tLS0tLS0tLS0tLSAjCgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZSgKICAjIE92ZXJhbGwgKG92ZXJsYXBwaW5nKSBwb3NpdGlvbgogIGdncGxvdChncmlkX2ZwX3NmKSArCiAgICBnZW9tX3NmKGRhdGEgPSBwb3J0X3NmLCBhZXMoKSwgZmlsbCA9IE5BKSArCiAgICBnZW9tX3NmKGFlcyhjb2xvciA9IHN0YXRlX3Bvc3RhbCksIGFscGhhID0gMC4zKSArCiAgICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsIGFlcygpLGZpbGwgPU5BKSArIAogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgdGhlbWVfZGFyaygpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICIiKSwKICAjIFNob3dpbmcgZWFjaCBzdGF0ZSBzZXBhcmF0ZWx5CiAgZ2dwbG90KCkgKwogICAgZ2VvbV9zZihkYXRhID0gZ3JpZF9mcF9zZiwgYWVzKGNvbG9yID0gc3RhdGVfcG9zdGFsKSxzaXplID0gMC4xLCBhbHBoYSA9IDAuNSkgKwogICAgZmFjZXRfd3JhcCh+c3RhdGVfcG9zdGFsKSArCiAgICB0aGVtZV9kYXJrKCkgKwogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpLAogIG5yb3cgPSAxKQoKYGBgCgojIyMjIDMuIENyb3AgYnVmZmVycyB0byBFRVoKCkZpbmFsbHksIHdlIGNyb3AgdGhlIGdyaWRlZCBidWZmZXJzIHRvIHdpdGhpbiB0aGUgRUVaIHRvIGNhcHR1cmUgdGhlIGFjdHVhbCB3YXRlciBzcGFjZS4KCipOb3RlOiogVGhpcyBzdGVwIHRha2VzIHF1aXRlIGEgd2hpbGUgYmVjYXVzZSBvZiB0aGUgc2l6ZSBvZiB0aGUgRUVaIHNoYXBlZmlsZS4gTm8sIHlvdSBjYW5ub3QgdXNlIGBzdF9zaW1wbGlmeSgpYCBoZXJlCgojIyMjIDMuMSBTdGF0ZSBXYXRlcnMKCmBgYHtyIGJ1ZmZfc3dfdG9fZWV6LCBldmFsID1ULCBlY2hvID0gVCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGfQoKIyBJIGRvbid0IGtub3cgaG93IHRvIHVuZG8gc3Rfc2ltcGxpZnkgc28gbmVlZCB0byByZS1sb2FkIHRoZSBzaGFwZWZpbGUKCmVlel9zZiA8LSBzdF9yZWFkKG15X3BhdGgoIkciLCBleHRyYV9wYXRoID0gIlNwYXRpYWwvU0FVL1NBVV9TaGFwZWZpbGUiLCBuYW1lID0gIlNBVUVFWl9KdWx5MjAxNS5zaHAiKSkgJT4lIAogIHJlbmFtZShlZXpfbmFtZSA9IE5hbWUpICU+JSAKICBzdF90cmFuc2Zvcm0oY3JzID0gNDMyNikgJT4lICMgNDMyNgogIGZpbHRlcihlZXpfbmFtZSA9PSAiVVNBIChFYXN0IENvYXN0KSIpIAoKIyBHZXQgdGhlIG92ZXJsYXBwaW5nIHNlZ21lbnRzIAojIE5PVEU6IFRha2VzIHNvbWUgZ29vb29vb2QgdGltZSAofjIwIG1pbikKU3lzLnRpbWUoKQpncmlkX2Vlel9zd19zZiA8LSBzdF9pbnRlcnNlY3Rpb24oZ3JpZF9zd19zZixlZXpfc2YpClN5cy50aW1lKCkKCiMgd3JpdGVfc2YoZ3JpZF9lZXpfc3dfc2YsIHBhc3RlMChteV9wYXRoKCJEIiwgIlNwYXRpYWwvZ3JpZF9lZXpfc3dfc2YiKSwiZ3JpZF9lZXpfc3dfc2Yuc2hwIikpCmdyaWRfZWV6X3N3X3NmIDwtIG15X3BhdGgoIkQiLCJTcGF0aWFsL2dyaWRfZWV6X3N3X3NmIiwgbmFtZSA9ICJncmlkX2Vlel9zd19kZi5jc3YiLHJlYWQgPSBUKQoKIyBHZXQgZmluYWwgZGYgd2l0aCBpbmRleApncmlkX2Vlel9zd19kZiA8LSBhcy5kYXRhLmZyYW1lKGdyaWRfZWV6X3N3X3NmKSAlPiUKICBzZWxlY3Qoc3RhdGUsYWJyZXYsaW5kZXgpICU+JQogIGxlZnRfam9pbihuZV9ncmlkLAogICAgICAgICAgICBieSA9ICJpbmRleCIpCgojIHdyaXRlX2NzdihncmlkX2Vlel9zd19kZiwgcGFzdGUwKG15X3BhdGgoIkQiLCAiU3BhdGlhbC9ncmlkX2Vlel9zd19zZiIsImdyaWRfZWV6X3N3X2RmLmNzdiIpKSkKCiMgUGxvdCB0byBtYWtlIHN1cmUgbWFrZXMgc2Vuc2UKCmVlel9zZiA8LSBlZXpfc2YgJT4lIAogIHN0X3NpbXBsaWZ5KHByZXNlcnZlVG9wb2xvZ3kgPSBUUlVFLCBkVG9sZXJhbmNlID0gMC4xKSAjMC4xIGZvciBwYXBlcgoKZ3JpZF9lZXpfc3dfZGYgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoYWVzKGNvbG9yID0gc3RhdGUpLCBhbHBoYSA9IDAuMykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpICsKICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsYWVzKCksIGZpbGwgPSBOQSkgKwogIHRoZW1lX2RhcmsoKQoKYGBgCgoKIyMjIyAzLjIgRmlzaGluZyBQb3J0cwoKYGBge3IgYnVmZl9mcF90b19lZXosIGV2YWwgPVQsIGVjaG8gPSBULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEZ9CgpzdGF0ZV9uYW1lcyA8LSBncmlkX2Vlel9zd19kZiAlPiUgCiAgc2VsZWN0KHN0YXRlLGFicmV2KSAlPiUgCiAgZGlzdGluY3QoLmtlZXBfYWxsID0gVCkKCiMgR2V0IHRoZSBvdmVybGFwcGluZyBzZWdtZW50cyAKIyBOT1RFOiBUYWtlcyBzb21lIGdvb29vb29kIHRpbWUgKH4yMCBtaW4pClN5cy50aW1lKCkKZ3JpZF9lZXpfc2ZfZnAgPC0gc3RfaW50ZXJzZWN0aW9uKGdyaWRfZnBfc2YsZWV6X3NmKQpTeXMudGltZSgpCgp3cml0ZV9zZihncmlkX2Vlel9zZl9mcCwgbXlfcGF0aCgiUiIsICJQYXJ0aWFsIixuYW1lPSJncmlkX2Vlel9mcC5zaHAiKSkKCiMgR2V0IGZpbmFsIGRmIHdpdGggaW5kZXgKZ3JpZF9lZXpfZnBfZGYgPC0gYXMuZGF0YS5mcmFtZShncmlkX2Vlel9zZl9mcCkgJT4lCiAgc2VsZWN0KGluZGV4LHBvcnRfbmFtZSxhYnJldj1zdGF0ZV9wb3N0YWwsc3BwPXNwZWNpZXNfbmFtZSkgJT4lIAogIGxlZnRfam9pbihuZV9ncmlkLAogICAgICAgICAgICBieSA9ICJpbmRleCIpCgp3cml0ZV9jc3YoZ3JpZF9lZXpfZnBfZGYsIG15X3BhdGgoIlIiLCAiUGFydGlhbC9ncmlkX2ZwIixuYW1lID0gImdyaWRfZWV6X2ZwX2RmLmNzdiIpKQoKIyBQbG90IHRvIG1ha2Ugc3VyZSBtYWtlcyBzZW5zZQpncmlkX2Vlel9zZl9mcCAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoY29sb3IgPSBzdGF0ZV9wb3N0YWwpLCBhbHBoYSA9IDAuMykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpICsKICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsYWVzKCksIGZpbGwgPSBOQSkgKwogIHRoZW1lX2RhcmsoKQoKYGBgCgojIyMjIDMuMyBEaWZmZXJlbmNlcyBhdCBjcm9wZWQgbGV2ZWwKCkJ5IGxvb2tpbmcgYXQgdGhlIHBsb3RzIHdlIGRvIG5vdCBzZWUgdGhhdCB0aGUgbnVtYmVyIG9mIGdyaWQgY2VsbHMgdGhhdCBlYWNoIHN0YXRlIGhhcyBpcyBzbGlnaHRseSBkaWZmZXJlbnQgZGVwZW5kaW5nIG9uIHRoZSBhcHByb2FjaC4gVGhpcyBjb21lcyB0byBsaWdodCB3aGVuIHdlIGNvdW50IHRoZSBudW1iZXIgb2YgZ3JpZGNlbGxzIHRoYXQgZWFjaCBzdGF0ZSBnZXRzIGluIGVhY2ggYXBwcm9hY2guIFdlIHNlZSB0aGF0IHRoZSBzdGF0ZSB3YXRlcnMgb25lIGlzIHN1YnN0YW50aWFsbHkgaGlnaGVyLgoKV2UgY2FuIHZpc3VhbGl6ZSB0aGUgZGlmZmVyZW5jZSBvZiB0aGUgY3JvcHBlZCBhcmVhIGZvciBlYWNoIHN0YXRlIG5leHQuIEFnYWluLCB0aGUgZmlzaGluZyBwb3J0IGFwcHJvYWNoIHJlc3VsdHMgaW4gbGVzcyBhcmVhIGZvciBhbGwgc3RhdGVzLCBidXQgc3VjaCBhcmVhIGlzIG5vdCBwcm9wb3J0aW9uYWwgYW1vbmcgc3RhdGVzLiBGb3IgZXhhbXBsZSwgRGVsYXdhcmUgbG9vc2VzIHJvdWdobHkgMzUlIG9mIGZpc2hpbmcgZ3JvdW5kcyB3aXRoIHRoaXMgYXBwcm9hY2gKCmBgYHtyIHN0YXRlX2JmX2RpZmZfbnRibCwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKZ3JpZF9lZXpfc3dfZGYgJT4lIAogIG11dGF0ZShhcHByb2FjaCA9ICJzdGF0ZV93YXRlcnMiKSAlPiUgCiAgYmluZF9yb3dzKGdyaWRfZWV6X2ZwX2RmKSAlPiUKICBtdXRhdGUoYXBwcm9hY2ggPSBpZmVsc2UoaXMubmEoYXBwcm9hY2gpLCJmaXNoaW5nX3BvcnQiLGFwcHJvYWNoKSkgJT4lIAogIGdyb3VwX2J5KHN0YXRlLGFwcHJvYWNoKSAlPiUgCiAgc3VtbWFyaXNlKG5fZ3JpZCA9IG4oKSkgJT4lIAogIHNwcmVhZChhcHByb2FjaCxuX2dyaWQpICU+JSAKICBtdXRhdGUoZGlmZmVyZW5jZSA9c3RhdGVfd2F0ZXJzLWZpc2hpbmdfcG9ydCwKICAgICAgICAgcGVyY2VudGFnZV9zdyA9IHJvdW5kKChkaWZmZXJlbmNlL3N0YXRlX3dhdGVycykqMTAwKQogICAgICAgICApCgpgYGAKCkFuZCBoZXJlIGlzIHRoZSBtYXAgdmlzdWFsaXphdGlvbiBvZiB0aGUgY3JvcHBlZCBkaWZmZXJlbmNlCgpgYGB7ciBzdGF0ZV9iZl9kaWZmX21hcCwgZXZhbCA9IFQsIGVjaG8gPSBUfQoKZ3JpZF9lZXpfc3dfZGYgJT4lIAogIG11dGF0ZShhcHByb2FjaCA9ICJzdGF0ZV93YXRlcnMiKSAlPiUgCiAgYmluZF9yb3dzKGdyaWRfZWV6X2ZwX2RmKSAlPiUKICBtdXRhdGUoYXBwcm9hY2ggPSBpZmVsc2UoaXMubmEoYXBwcm9hY2gpLCJmaXNoaW5nX3BvcnQiLGFwcHJvYWNoKSkgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX3RpbGUoCiAgICBhZXMoCiAgICAgIHggPSBsb24sCiAgICAgIHkgPSBsYXQsCiAgICAgIGZpbGwgPSBhcHByb2FjaAogICAgKSwKICAgIGFscGhhID0gMC41CiAgKSArCiAgZmFjZXRfd3JhcCh+c3RhdGUpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsKICB0aGVtZV9kYXJrKCkKCmBgYAoKCiMjIyBJbnRlcnBvbGF0aW9uIHJ1dGluZQoKSW4gdGhpcyBzdGVwIHdlIFtpbnRlcnBvbGF0ZV0oaHR0cHM6Ly9zd2lsa2UtZ2Vvc2NpZW5jZS5uZXQvcG9zdC9zcGF0aWFsX2ludGVycG9sYXRpb24vKSB0aGUgc3VydmV5IGRhdGEgd2l0aGluIHRoZSBwcmV2aW91c2x5IGNyZWF0ZWQgZ3JpZCBmb2xsb3dpbmcgYSBUcmlhbmd1bGFyIElycmVndWxhciBTdXJmYWNlIG1ldGhvZC4KCiMjIyMgRnVuY3Rpb25zIG5lZWRlZAoKV2UgbmVlZCB0byBjcmVhdGUgYSBjb3VwbGUgb2YgZnVuY3Rpb25zIHRvIHJ1biB0aGUgd2hvbGUgcHJvY2VzcwoKIyMjIyMgSW50ZXJwb2xhdGlvbiBtYWluIGZ4ICh0aXMpLgoKVGhpcyBpcyB0aGUgbWFpbiBmdW5jdGlvbiB1c2VkIHRvIGludGVycG9sYXRlIHRoZSBkYXRhIHBlciB5ZWFyLiBJdCBmb2xsb3dzIGEgVHJpYW5ndWxhciBJcnJlZ3VsYXIgU3VyZmFjZSBtZXRob2QgdXNpbmcgdGhlIGBpbnRlcnA6OmludGVycCgpYCBmdW5jdGlvbi4gSWYgeW91IHdhbnQgdG8gc2VlIHRoZSBmdW5jdGlvbiBjbGljIG9uIGBjb2RlYAoKYGBge3IgaW50ZXJwb2xfZnVuY3Rpb24sIGV2YWwgPSBULCBlY2hvID0gVH0KCnRpcyA8LSBmdW5jdGlvbihpbnB1dF9kYXRhLCBncmlkLCB5ciwgdGF4YSwgcmVnKXsKICAKICAjIC0tLS0tLS0tLS0tLS0tLSAjCiAgIyBUZXN0aW5nCiAgIyBwcmludChwYXN0ZSh5cikpCiAgIyB5ciA9IDE5NzYKICAjIC0tLS0tLS0tLS0tLS0tLSAjCiAgCiAgIyBGaWx0ZXIgZGF0YQogIGRhdGEgPC0gaW5wdXRfZGF0YSAlPiUgCiAgICBmaWx0ZXIoeWVhciA9PSB5ciwKICAgICAgICAgICBzcHAgPT0gdGF4YSwKICAgICAgICAgICByZWdpb24gPT0gcmVnCiAgICApICU+JSAKICAgICMgQXZlcmFnZSBkdXBsaWNhdGVkIGhhdWxzIGluIHRoZSBzYW1lIHNwb3QKICAgIGdyb3VwX2J5KHJlZ2lvbix5ZWFyLHNwcCxsYXQsbG9uKSAlPiUKICAgIHN1bW1hcmlzZV9hdCh2YXJzKHd0Y3B1ZSksCiAgICAgICAgICAgICAgICAgbWVhbixuYS5ybSA9IFQpCiAgICAKICAjIE9ubHkgaW50ZXJwb2xhdGUgY2FzZXMgd2hlcmUgdGhlcmUgaXMgbW9yZSB0aGFuIDMgcm93cwogICMgTWFya2VkIGJ5IHRoZSBmdW5jdGlvbiAKICAgIGlmKG5yb3coZGF0YSkgPD0gMyl7CiAgICAgIGZpdF90aW4gPC0gdGliYmxlKCkKICAgIH1lbHNlewogICAgICAKICAgICAgIyBUcmlhbmd1bGFyIElycmVndWxhciBTdXJmYWNlCiAgICAgIGZpdF90aW4gPC0gaW50ZXJwOjppbnRlcnAoICMgdXNpbmcge2ludGVycH0KICAgICAgICB4ID0gZGF0YSRsb24sICAgICAgICAgICAjIHRoZSBmdW5jdGlvbiBhY3R1YWxseSBhY2NlcHRzIGNvb3JkaW5hdGUgdmVjdG9ycwogICAgICAgIHkgPSBkYXRhJGxhdCwKICAgICAgICB6ID0gZGF0YSR3dGNwdWUsCiAgICAgICAgeG8gPSBncmlkJGxvbiwgICAgICMgaGVyZSB3ZSBhbHJlYWR5IGRlZmluZSB0aGUgdGFyZ2V0IGdyaWQKICAgICAgICB5byA9IGdyaWQkbGF0LAogICAgICAgIG91dHB1dCA9ICJwb2ludHMiCiAgICAgICkgJT4lIAogICAgICAgIGJpbmRfY29scygpICU+JSAKICAgICAgICBiaW5kX2NvbHMoZ3JpZCkgJT4lCiAgICAgICAgbXV0YXRlKHllYXIgPSB5ciwKICAgICAgICAgICAgICAgcmVnaW9uID0gcmVnLAogICAgICAgICAgICAgICBzcHAgPSB0YXhhKSAlPiUgCiAgICAgICAgc2VsZWN0KGluZGV4LCAKICAgICAgICAgICAgICAgIyBzdGF0ZSwKICAgICAgICAgICAgICAgeWVhciwgcmVnaW9uLCBzcHAsIGxvbj14LCBsYXQ9eSwgdmFsdWUgPSB6KQogICAgICAKICAgIH0KICAgCiAgICByZXR1cm4oZml0X3RpbikKfQoKIyBUZXN0IG1lCiMgTmVlZHMgdmFyaWFibGVzIGluIENvbnRyb2wgcGFuZWwKIyBUZXN0IG5vIGRhdGE6ICJBbG9zYSBhZXN0aXZhbGlzIiwgcmVnID0gIk5vcnRoZWFzdCBVUyBGYWxsIiwgeXIgPSAxOTc0IAojIHRpcyhpbnB1dF9kYXRhID0gb2NlYW5fZGF0YSwgZ3JpZCA9IGdyaWRfZWV6X2RmLCB0YXhhID0gIklsbGV4IGlsbGVjZWJyb3N1cyIsIHJlZyA9ICJOb3J0aGVhc3QgVVMgRmFsbCIsIHlyID0gMTk3MykKCgoKIyBsYXBwbHkoeWVhcnMsdGlzLGlucHV0X2RhdGEgPSBvY2Vhbl9kYXRhLCBncmlkID0gZ3JpZF9lZXpfZGYsIHRheGEgPSAiSWxsZXggaWxsZWNlYnJvc3VzIiwgcmVnID0gcmVnaW9uc1syXSkKCmBgYAoKIyMjIyMgUnVuIGZ1bmN0aW9uCgpUaGlzIGlzIGEgc3ViLWZ1bmN0aW9uIHRoYXQgcnVucyB0aGUgYHRpcygpYCBmdW5jdGlvbiBieSB0YXhhIGFuZCByZWdpb24uIEl0IHNhdmVzIHRoZSBvdXRwdXQgYXMgYSAuY3N2IGZpbGUgZm9yIGVhY2ggc3BlY2llcy4gCgpgYGB7ciBpbnRlcnBvbF9ydW5fZnVuLCBldmFsID0gVCwgZWNobyA9IFR9CgoKcnVuX3RpcyA8LSBmdW5jdGlvbihpbnB1dF9kYXRhLCBncmlkLCB5ZWFycywgdGF4YSwgcmVnKXsKICAKICAKICAjIFJ1biB0aXMgZm9yIHNwZWNpZXMgYW5kIHN1cnZleXMKICBmb3IociBpbiAxOjIpewogICAgCiAgICBwYXJ0aWFsX2RmIDwtIGJpbmRfcm93cygKICAgICAgbGFwcGx5KHllYXJzLHRpcyxpbnB1dF9kYXRhID0gaW5wdXRfZGF0YSwgZ3JpZCA9IGdyaWQsIHRheGEgPSB0YXhhLCByZWcgPSByZWdbcl0pCiAgICApCiAgICAKICAgIGlmKHIgPT0gMSl7CiAgICAgIGhpc3RvcmljX3RpZiA8LSBwYXJ0aWFsX2RmCiAgICB9ZWxzZXsKICAgICAgaGlzdG9yaWNfdGlmIDwtIGJpbmRfcm93cyhoaXN0b3JpY190aWYscGFydGlhbF9kZikKICAgIH0KICAgIAogIH0KICAKICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAjIFNhdmUgZGF0YXNldCBwZXIgc3BlY2llcwogICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogIAogICMgU2V0IGZpbGUgbmFtZQogIG5hbWUgPC0gcGFzdGUwKCJ0aWZfIixzdHJfcmVwbGFjZSh0YXhhLCIgIiwiXyIpLCIuY3N2IikKICAKICBjb21wbGVtZW50IDwtIHBhc3RlMCgiUGFydGlhbC9JbnRlcnBvbGF0aW9uLyIpCiAgCiAgIyBTZXQgcGF0aCBuYW1lCiAgc2F2ZV9wYXRoIDwtIG15X3BhdGgoIlIiLGNvbXBsZW1lbnQpCiAgCiAgIyBTZXQgY29tcGxldGUgcGF0aAogIHNhdmVfbmFtZSA8LSBwYXN0ZTAoc2F2ZV9wYXRoLG5hbWUpCiAgCiAgIyBDcmVhdGUgZm9sZGVyIGlmIGl0IGRvZXMgbm90IGV4aXN0CiAgaWYoZmlsZS5leGlzdHMoc2F2ZV9wYXRoKSA9PSBGKXsKICAgIGRpci5jcmVhdGUoc2F2ZV9wYXRoKQogIH0KICAKICAjICBTYXZlIGZpbGUKICB3cml0ZV9jc3YoaGlzdG9yaWNfdGlmLHNhdmVfbmFtZSkKICAKICByZXR1cm5fbXNnIDwtIHBhc3RlKCJJbnRlcnBvbGF0aW9uIGRvbmUgZm9yIiwgdGF4YSkKICAKICByZXR1cm4ocmV0dXJuX21zZykKICAKICAKfQoKIyBUZXN0IG1lCiAgICAjIHJ1bl90aXMoaW5wdXRfZGF0YSA9IG9jZWFuX2RhdGEsIGdyaWQgPSBncmlkX2Vlel9mcF9kZiwgdGF4YSA9ICJDZW50cm9wcmlzdGlzIHN0cmlhdGEiLCB5ZWFycyA9IHNlcSgxOTcwLDE5ODApLCByZWcgPSByZWdpb25zLCBtZXRob2QgPSAidGVzdGEiKQoKYGBgCgoKIyMjIyBTdXJ2ZXkgZGF0YQoKVGhlIGludGVycG9sYXRpb24gd2FzIGRvbmUgd2l0aCBOT0FBIE5vcnRoZWFzdCBGaXNoZXJpZXMgU2NpZW5jZSBDZW50ZXIgU3ByaW5nIGFuZCBGYWxsIEJvdHRvbSBUcmF3bCBTdXJ2ZXlzIFtkYXRhXShodHRwczovL3d3dy5maXNoZXJpZXMubm9hYS5nb3YvcmVnaW9uL25ldy1lbmdsYW5kLW1pZC1hdGxhbnRpYyNzY2llbmNlKSBwcm92aWRlZCBieSBbT2NlYW4gYWRhcHRdKGh0dHBzOi8vb2NlYW5hZGFwdC5ydXRnZXJzLmVkdS8pLiBEYXRhIHdhcyBhY2Nlc3NlZCB0cm91Z2ggdGhlIFtHaXRodWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9waW5za3lsYWIvT2NlYW5BZGFwdCkuCgoqSW4gcHJpbWFyeSBwdWJsaWNhdGlvbnMgdXNpbmcgZGF0YSBmcm9tIHRoZSBkYXRhYmFzZSwgcGxlYXNlIGNpdGUgUGluc2t5IGV0IGFsLiAyMDEzLiBNYXJpbmUgdGF4YSB0cmFjayBsb2NhbCBjbGltYXRlIHZlbG9jaXRpZXMuIFNjaWVuY2UgMzQxOiAxMjM5LTEyNDIgZG9pOiAxMC4xMTI2L3NjaWVuY2UuMTIzOTM1MiwgYXMgd2VsbCBhcyB0aGUgb3JpZ2luYWwgZGF0YSBzb3VyY2VzLioKCi0gVXNpbmcgb25seSB0aGUgTm9ydGhlYXN0IFVTIEZhbGwgYW5kIFNwcmluZyBib3R0b20gdHJhd2wgc3VydmV5IGRhdGEgZm9yIG5vdwoKIyMjIyMgU3BsaXR0aW5nIHVwIGRhdGEKCi0gTm8gcGFydCBvbiBzcGF0aWFsIGFuYWx5c2lzLiBDYW4gYmUgaWdub3JlZC4gCgpUaGlzIGlzIGp1c3QgYSBzdWItc3RlcCB0byBzcGxpdCB1cCB0aGUgZGF0YSBpbnRvIHNpbmdsZSBzcGVjaWVzIGZpbGVzLiBUaGlzIG1ha2VzIHRoZSBhcHAgZmFzdGVyIGFzIGl0IG9ubHkgbmVlZHMgdG8gbG9hZCBzcGVjaWVzIHNwZWNpZmljIGRhdGEsIHJhdGhlciB0aGFuIGFsbCB0aGUgZGF0YSBhdCBkZSBiZWdpbm5pbmcuIAoKYGBge3IgZGF0X2V4cGxvZGVkLCBldmFsID0gRiwgZWNobyA9IEYsIGZpZy53aWR0aCA9IDl9CgpvY2Vhbl9kYXRhIDwtIHJlYWRSRFMoIi9Wb2x1bWVzL0VudGVycHJpc2UvRGF0YS9waW5za3lsYWItT2NlYW5BZGFwdC05NjZhZGYwL2RhdGFfY2xlYW4vZGF0X2V4cGxvZGVkLnJkcyIpICMlPiUgCiAgIyBmaWx0ZXIoc3BwID09ICJDZW50cm9wcmlzdGlzIHN0cmlhdGEiLAogICAgICAgIyByZWdpb24gJWluJSBjKCJOb3J0aGVhc3QgVVMgRmFsbCIgLCAiTm9ydGhlYXN0IFVTIFNwcmluZyIpKSAjTm8gbW9yZSBzZWFzb25zCgoKc3BwX2RhdGEgPC0gZnVuY3Rpb24oc3BwKXsKICAKICBuYW1lX3NhdmUgPC0gcGFzdGUwKG15X3BhdGgoIkQiLCJTcHAvT2JzZXJ2YXRpb24iKSwib2JzXyIsc3RyX3JlcGxhY2Uoc3BwWzFdLCAiICIsICJfIiksIi5jc3YiKQoKb2NlYW5fZGF0YSAlPiUgCiAgZmlsdGVyKHNwcCA9PSBzcHAsCiAgICAgICByZWdpb24gJWluJSBjKCJOb3J0aGVhc3QgVVMgRmFsbCIgLCAiTm9ydGhlYXN0IFVTIFNwcmluZyIpCiAgICAgICApICU+JSAKICB3cml0ZV9jc3YoLiwgbmFtZV9zYXZlKQogIAp9CgpzcHBfbGlzdCA8LSBvY2Vhbl9kYXRhICU+JSAKICBmaWx0ZXIocmVnaW9uICVpbiUgcmVnaW9ucywKICAgICAgICAgc3BwICE9ICJOQSIpICU+JSAKICBwdWxsKHNwcCkgJT4lIAogIHVuaXF1ZSgpCiAgCgpsYXBwbHkoc3BwX2xpc3QsIHNwcF9kYXRhKQoKCnN1YnNldF9kYXRhIDwtIG9jZWFuX2RhdGEgJT4lIAogIGZpbHRlcihzcHAgPT0gIkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIsCiAgICAgICByZWdpb24gJWluJSBjKCJOb3J0aGVhc3QgVVMgRmFsbCIgLCAiTm9ydGhlYXN0IFVTIFNwcmluZyIpCiAgICAgICApCgpnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3Vic2V0KHN1YnNldF9kYXRhLCB3dGNwdWUgPSAwLjApLAogICAgICAgICAgICAgYWVzKAogICAgICAgICAgICAgICB4ID0gbG9uLAogICAgICAgICAgICAgICB5ID0gbGF0CiAgICAgICAgICAgICApLAogICAgICAgICAgICAgY29sb3IgPSAiZ3JleTk1IgogICkgKwogIGdlb21fcG9pbnQoZGF0YSA9IHN1YnNldChzdWJzZXRfZGF0YSwgd3RjcHVlID4gMCksCiAgICAgICAgICAgICBhZXMoCiAgICAgICAgICAgICAgIHggPSBsb24sCiAgICAgICAgICAgICAgIHkgPSBsYXQsCiAgICAgICAgICAgICAgIGNvbG9yID0gbG9nMTAod3RjcHVlKQogICAgICAgICAgICAgKSwKICAgICAgICAgICAgIHNpemUgPSAxCiAgKSArCiAgc2NhbGVfY29sb3JfZGlzdGlsbGVyKHBhbGV0dGUgPSAiU3BlY3RyYWwiLCAKICAgICAgICAgICAgICAgICAgICAgICAgZ3VpZGVfbGVnZW5kKHRpdGxlID0gIldDUFVFIHBlciBIYXVsIChsb2cxMCkiKSkgKyAKICBjb29yZF9zZih4bGltID0gYygtNzYsIC02NSkseWxpbSA9IGMoMzUsIDQ1KSkgKwogIE15RnVuY3Rpb25zOjpteV9nZ3RoZW1lX20oKSArCiAgZmFjZXRfd3JhcCh+cmVnaW9uKQoKYGBgCgojIyMjIENvbnRyb2wgUGFubmVsCgpUaGlzIGlzIHdoZXJlIHdlIGxvYWQgdGhlIHJlcXVpcmVkIGRhdGEgYW5kIHByZXBhcmUgdG8gcnVuIHRoZSBpbnRlcnBvbGF0aW9uIGZ1bmN0aW9uLiBOb3RlIHRoYXQgc29tZSBvZiB0aGUgZGF0YSBoZXJlIGhhcyBiZWVuIHByZXZpb3VzbHkgY3JlYXRlZCAKCmBgYHtyIGNvbnRyb19wYW5uZWwsIGV2YWwgPSBULCBlY2hvID0gVH0KCiMgTG9hZCBncmlkIGRmCiMgRm9yIGZpc2hpbmcgcG9ydHMKaW50ZXJfZ3JpZCA8LSBteV9wYXRoKCJEIiwiU3BhdGlhbCIsImludGVyX2dyaWRfZGYuY3N2IiwgcmVhZCA9IFQpCgojIFJ1biBpbnRlcnBvbGF0aW9uIGZvciBhbGwgeWVhcnMKeWVhcnMgPC0gc2VxKDE5NzMsMjAxOSwxKQoKIyByZWdpb25zCnJlZ2lvbnMgPC0gYygiTm9ydGhlYXN0IFVTIEZhbGwiICwgIk5vcnRoZWFzdCBVUyBTcHJpbmciKQoKIyBzcGVjaWVzIGxpc3QKc3BwIDwtIG9jZWFuX2RhdGEgJT4lIAogIGZpbHRlcihyZWdpb24gJWluJSByZWdpb25zLAogICAgICAgICBzcHAgIT0gIk5BIikgJT4lIAogIHB1bGwoc3BwKSAlPiUgCiAgdW5pcXVlKCkKCgojIERvdWJsZSBjaGVjayBydW5zCgpzcHBfcnVucyA8LSB0aWJibGUodGF4YSA9IChsaXN0LmZpbGVzKG15X3BhdGgoIlIiLCJQYXJ0aWFsL0ludGVycG9sYXRpb24vZnAiKSkpKSAlPiUKICBtdXRhdGUoCiAgICB0YXhhID0gc3RyX3JlbW92ZSh0YXhhLCAidGlmXyIpLAogICAgdGF4YSA9IHN0cl9yZW1vdmUodGF4YSwgIi5jc3YiKSwKICAgIHRheGEgPSBzdHJfcmVwbGFjZSh0YXhhLCAiXyIsICIgIikKICApIAoKIyBNaXNzaW5nIHJ1bnMKc3BwIDwtIHRpYmJsZSh0YXhhPXNwcCkgJT4lIAogIGFudGlfam9pbihzcHBfcnVucykgJT4lIAogIHB1bGwodGF4YSkKCgpgYGAKCiMjIyMgUnVuIHJvdXRpbmUKCkhlcmUgd2UganVzdCBydW4gdGhlIHJvdXRpbmUgZm9yIGVhY2ggb2YgdGhlIHNwZWNpZXMgcHJlc2VudCBpbiB0aGUgTm9ydGhlYXN0IFVTIEZhbGwgYW5kIFNwcmluZyBzdXJ2ZXlzIGJldHdlZW4gMTk3MyBhbmQgMjAxOS4gCgotIE5vdGUgdGhlcmUgYXJlIDQzIGlkZW50aWZpZWQgdGF4YQotIFNvbWUgdGF4YSBkbyBub3QgaGF2ZSBwcmVzZW5jZSBkYXRhIGluIHNvbWUgeWVhcnMKCmBgYHtyIHJ1bl9yb3V0aW5lLCBldmFsID0gVCwgZWNobyA9IFR9CgojICMgc2luZ2xlIHNwZWNpZXMgcnVuCnJ1bl90aXMoaW5wdXRfZGF0YSA9IG9jZWFuX2RhdGEsCiAgICAgICAgZ3JpZCA9IGdyaWRfZWV6X2ZwX2RmLAogICAgICAgIHllYXJzID0geWVhcnMsCiAgICAgICAgcmVnID0gcmVnaW9ucywKICAgICAgICB0YXhhID0gIlN0ZW5vdG9tdXMgY2hyeXNvcHMiLAogICAgICAgIG1ldGhvZCA9ICJmcCIKKQoKCiMgUnVuIHRoZW0gYWxsIGluIHBhcmFsbGVsCmxhcHBseShTcGVjaWVzLAogICAgICAgcnVuX3RpcywgCiAgICAgICBpbnB1dF9kYXRhID0gb2NlYW5fZGF0YSwKICAgICAgIGdyaWQgPSBpbnRlcl9ncmlkLAogICAgICAgeWVhcnMgPSB5ZWFycywKICAgICAgIHJlZyA9IHJlZ2lvbnMKKQoKCmBgYAoKIyBSZXN1bHRzCgpSZXN1bHRzIGFyZSBub3cgZm9yIGVpZ2h0IHNwZWNpZXMgbWFuYWdlZCB1bmRlciBNaWQtQXRsYW50aWMgQ291bmNpbCBNYW5hZ2VtZW50IFBsYW5zIGFjY29yZGluZyB0byBbTk9BQV0oaHR0cHM6Ly93d3cuZmlzaGVyaWVzLm5vYWEuZ292L25ldy1lbmdsYW5kLW1pZC1hdGxhbnRpYy9jb21tZXJjaWFsLWZpc2hpbmcvbmV3LWVuZ2xhbmQtbWlkLWF0bGFudGljLWZpc2hlcnktbWFuYWdlbWVudC1wbGFucykuCgoKU3RhdGUgYWxsb2NhdGlvbnMgb2YgdGhlIGNvbW1lcmNpYWwgYmxhY2sgc2VhIGJhc3MgY29hc3R3aWRlIHF1b3RhIHdlcmUgb3JpZ2luYWxseSBpbXBsZW1lbnRlZCBpbiAyMDAzIGFzIHBhcnQgb2YgQW1lbmRtZW50IDEzLCBsb29zZWx5IGJhc2VkIG9uIGhpc3RvcmljYWwgbGFuZGluZ3MgZnJvbSAxOTgwLSAyMDAxLiAKCgoqU2NvbWJlciBzY29tYnJ1cyosICpQZXByaWx1cyB0cmlhY2FudGh1cyogKGJ1dHRlcmZpc2gpLCAqSWxsZXggaWxsZWNlYnJvc3VzKiAoc2hvcnRmaW4gc3F1aWQpLCAqUGFyYWxpY2h0aHlzIGRlbnRhdHVzKiAoc3VtbWVyIGZsb3VuZGVyKSwgKlN0ZW5vdG9tdXMgY2hyeXNvcHMqIChTY29vcCksICpDZW50cm9wcmlzdGlzIHN0cmlhdGEqIChibGFjayBzZWEgYmFzcyksICpQb21hdG9tdXMgc2FsdGF0cml4KiAoQmx1ZWZpc2gpLCAqTG9waG9sYXRpbHVzIGNoYW1hZWxlb250aWNlcHMqIChHb2xkZW4gdGlsZWZpc2gpLCAqQ2F1bG9sYXRpbHVzIG1pY3JvcHMqIChibHVlbGluZSB0aWxlZmlzaCkgYW5kICpDbHVwZWEgaGFyZW5ndXMqCgoKYGBge3IgbG9hZF9kYXRhLCBldmFsID0gVCwgZWNobyA9IFR9CgojIFNwYXRpYWwgZGF0YQpTdGF0ZXMgPC0gYygibWFpbmUiLCAibmV3IGhhbXBzaGlyZSIsICJtYXNzYWNodXNldHRzIiwgImNvbm5lY3RpY3V0IiwgInJob2RlIGlzbGFuZCIsICJuZXcgeW9yayIsICJuZXcgamVyc2V5IiwgImRlbGF3YXJlIiwgIm1hcnlsYW5kIiwgInZpcmdpbmlhIiwgIm5vcnRoIGNhcm9saW5hIikgCgojIFVTIFN0YXRlIE1hcCAobGFuZCkKbGFuZF9zZiA8LSBzdF9hc19zZihtYXAoInN0YXRlIiwgcGxvdCA9IEZBTFNFLCBmaWxsID0gVFJVRSkpICU+JSAKICBmaWx0ZXIoSUQgJWluJSBTdGF0ZXMpICU+JSAKICBtdXRhdGUoYWJyZXYgPSBjKCJDVCIsIkRFIiwiTUUiLCJNRCIsIk1BIiwiTkgiLCJOSiIsIk5ZIiwiTkMiLCJSSSIsIlZBIiksCiAgICAgICAgIHN0YXRlID0gc3RyX3RvX3NlbnRlbmNlKElEKQogICAgICAgICApCgojIFVTIEVFWiBtYXAKcGF0aF93b3JsZCA8LSBteV9wYXRoKCJHIiwgZXh0cmFfcGF0aCA9ICJTcGF0aWFsL1NBVS9TQVVfU2hhcGVmaWxlIiwgbmFtZSA9ICJTQVVFRVpfSnVseTIwMTUuc2hwIikKCgojIyMgUHJldmlvdXNsbHkgY3JlYXRlZCBncmlkcyAKCmdyaWRzIDwtIG15X3BhdGgoIkQiLCAiU3BhdGlhbC9ncmlkX2Vlel9mcCIsIG5hbWUgPSAiZ3JpZF9lZXpfZnBfZGYuY3N2IiwgcmVhZCA9IFQpICU+JQogIG11dGF0ZSgKICAgIHNwYXRpYWwgPSAiZnAiCiAgKSAlPiUgCiAgYmluZF9yb3dzKAogICAgbXlfcGF0aCgiRCIsICJTcGF0aWFsL2dyaWRfZWV6X3N3IiwgbmFtZSA9ICJncmlkX2Vlel9zd19kZi5jc3YiLCByZWFkID0gVCkKICApICU+JSAKICBzZWxlY3QoLXNwcCkgJT4lIAogIG11dGF0ZSgKICAgIHNwYXRpYWwgPSBpZmVsc2UoaXMubmEoc3BhdGlhbCksInN3IixzcGF0aWFsKQogICkgJT4lIAogIGRpc3RpbmN0KC5rZWVwX2FsbCA9IFQpCiAgCgojIFNwZWNpZXMgZGF0YQoKIyBNYW5hZ2VkIHNwZWNpZXMgYnkgTWlkLUF0bGFudGljIENvdW5jaWwgTWFuYWdlbWVudCBQbGFucywgYW5kIFN0YXRlIHdhdGVycwojIGh0dHBzOi8vd3d3LmZpc2hlcmllcy5ub2FhLmdvdi9uZXctZW5nbGFuZC1taWQtYXRsYW50aWMvY29tbWVyY2lhbC1maXNoaW5nL25ldy1lbmdsYW5kLW1pZC1hdGxhbnRpYy1maXNoZXJ5LW1hbmFnZW1lbnQtcGxhbnMKClNwZWNpZXMgPC0gYygKICAiUGFyYWxpY2h0aHlzIGRlbnRhdHVzIiwgI3N1bW1lciBmbG91bmRlcgogICJTdGVub3RvbXVzIGNocnlzb3BzIiwgI1NjdXAiCiAgIkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIjLCAjIGJsYWNrIHNlYSBiYXNzCiAgKQoKc3BwX3BhdGhzIDwtIGxpc3QuZmlsZXMobXlfcGF0aCgiUiIsZXh0cmFfcGF0aCA9ICJQYXJ0aWFsL0ludGVycG9sYXRpb24vIikpCgojIFNvbWUgZ2liaXJpcyBmb3IgbmFtZXMKdGF4b25fbGlzdCA8LSBnc3ViKCJfIiwiICIsc3BwX3BhdGhzKQp0YXhvbl9saXN0IDwtIGdzdWIoInRpZiAiLCIiLHRheG9uX2xpc3QpCnRheG9uX2xpc3QgPC0gZ3N1YigiLmNzdiIsIiIsdGF4b25fbGlzdCkKCnRheG9uX2xpc3QgPC0gdGF4b25fbGlzdFt0YXhvbl9saXN0ICVpbiUgU3BlY2llc10KCiMgTm93IHNldCBhIGxpc3Qgb2YgZmlsZXMgdG8gcmVhZAp0YXhvbl9yZWFkIDwtIHBhc3RlMCgidGlmXyIsdGF4b25fbGlzdCwiLmNzdiIpCnRheG9uX3JlYWQgPC0gZ3N1YigiICIsIl8iLHRheG9uX3JlYWQpCgp0YXhvbl9yZWFkIDwtIHNwcF9wYXRoc1tzcHBfcGF0aHMgJWluJSB0YXhvbl9yZWFkXQoKIyMjIyBMb2FkIHN3IGludGVycG9sYXRpb24gCgp0YXhvbl9zdyA8LSBteV9wYXRoKCJSIixleHRyYV9wYXRoID0gIlBhcnRpYWwvSW50ZXJwb2xhdGlvbi8iLCBuYW1lID0gdGF4b25fcmVhZCkKCiMgTG9hZCBhbGwgc3AgaW4gb25lIHRhYmxlCmhpc3RvcmljX3NwcCA8LSBiaW5kX3Jvd3MobGFwcGx5KHRheG9uX3N3LCBmcmVhZCkpICU+JSAKICBsZWZ0X2pvaW4oZ3JpZHMsCiAgICAgICAgICAgIGJ5ID0gYygiaW5kZXgiLCJsb24iLCJsYXQiKQogICkgJT4lCiAgZmlsdGVyKCFpcy5uYShzcGF0aWFsKSkgJT4lIAogIG11dGF0ZSgKICAgIHNlYXNvbiA9IGlmZWxzZShzdHJfZGV0ZWN0KHJlZ2lvbiwiU3ByaW5nIiksIlNwcmluZyIsIkZhbGwiKSwKICAgIGxhYmVsID0gaWZlbHNlKHNwcCA9PSAiUGFyYWxpY2h0aHlzIGRlbnRhdHVzIiAmIHllYXIgPj0gMTk4MCAmIHllYXIgPD0gMTk4NiwiUmVmZXJlbmNlIiwKICAgICAgICAgICAgICAgICAgIGlmZWxzZShzcHAgPT0gIlN0ZW5vdG9tdXMgY2hyeXNvcHMiICYgeWVhciA+PSAxOTg4ICYgeWVhciA8PSAxOTkyLCJSZWZlcmVuY2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSggc3BwID09IkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIgJiB5ZWFyID49IDE5ODAgJiB5ZWFyIDw9IDIwMDEsIlJlZmVyZW5jZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyID4gMjAwMSwiVG9kYXkiLE5BKQogICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICkKICAgICkKICApCgojIGhpc3RvcmljX3NwcCAlPiUgCiMgICBmaWx0ZXIoaXMubmEoc3BhdGlhbCkpICU+JSAKIyAgIGZpbHRlcih5ZWFyID09IDE5NzMsCiMgICAgICAgICAgcmVnaW9uID09ICJOb3J0aGVhc3QgVVMgRmFsbCIpICU+JSAKIyAgIGdncGxvdCgpICsKIyAgICAgZ2VvbV90aWxlKAojICAgICAgIGFlcygKIyAgICAgICAgIHggPSBsb24sCiMgICAgICAgICB5ID0gbGF0LAojICAgICAgICAgZmlsbCA9IGluZGV4CiMgICAgICAgKQojICAgICApICsKIyAgIGZhY2V0X2dyaWQoc3BwfnN0YXRlKSArIAojICAgZ2VvbV9zZihkYXRhID0gbGFuZF9zZixhZXMoKSkgKwojICAgZ2VvbV9zZihkYXRhID0gZWV6X3NmLCBhZXMoKSwgZmlsbCA9TkEpCgp1bmlxdWUoaGlzdG9yaWNfc3BwJHNwcCkKdW5pcXVlKGhpc3RvcmljX3NwcCRyZWdpb24pCnVuaXF1ZShoaXN0b3JpY19zcHAkc2Vhc29uKQoKIyBQZXJpb2RzCnBlcmlvZHMgPC10aWJibGUoCiAgb3JkZXIgPSBjKHJlcCgiYSIsMTIpLAogICAgICAgICAgICByZXAoImIiLDEyKSwKICAgICAgICAgICAgcmVwKCJjIiwxMiksCiAgICAgICAgICAgIHJlcCgiZCIsMTEpCiAgKSwKICBsYWJlbCA9IGMocmVwKCIxOTczLTE5ODQiLDEyKSwKICAgICAgICAgICAgcmVwKCIxOTg1LTE5OTYiLDEyKSwKICAgICAgICAgICAgcmVwKCIxOTk3LTIwMDgiLDEyKSwKICAgICAgICAgICAgcmVwKCIyMDA5LTIwMTkiLDExKQogICksCiAgeWVhciA9IGMoc2VxKDE5NzMsMTk4NCwxKSwKICAgICAgICAgICBzZXEoMTk4NSwxOTk2LDEpLAogICAgICAgICAgIHNlcSgxOTk3LDIwMDgsMSksCiAgICAgICAgICAgc2VxKDIwMDksMjAxOSwxKQogICkKICApCgoKc3RhdGVfbGF0IDwtIGhpc3RvcmljX3NwcCAlPiUKICBncm91cF9ieShzdGF0ZSkgJT4lIAogIHN1bW1hcmlzZSgKICAgIG9yZGVyID0gbWVhbihsYXQpCiAgKSAlPiUgCiAgZmlsdGVyKCFpcy5uYShzdGF0ZSkpICU+JSAKICBtdXRhdGUoYWJyZXYgPSBjKCJDVCIsIkRFIiwiTUUiLCJNRCIsIk1BIiwiTkgiLCJOSiIsIk5ZIiwiTkMiLCJSSSIsIlZBIikKICApICU+JSAKICBhcnJhbmdlKGRlc2Mob3JkZXIpKSAlPiUgCiAgbXV0YXRlKGxhdCA9IG9yZGVyLAogICAgIyBvcmRlciA9IGxldHRlcnNbMToxMV0sCiAgICBvcmRlciA9IGMoImIiLCJhIixsZXR0ZXJzWzM6MTFdKSwpCgoKCiMgU3RhdGUgcGFsbGV0CgpzdGF0ZV9wYWxsZXQgPC0gYyh3ZXNfcGFsZXR0ZShuID0gNSwgbmFtZSA9ICJEYXJqZWVsaW5nMSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VzX3BhbGV0dGUobiA9IDUsIG5hbWUgPSAiRGFyamVlbGluZzIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgd2VzX3BhbGV0dGUobiA9IDIsIG5hbWUgPSAiR3JhbmRCdWRhcGVzdDEiKQogICAgICAgICAgICAgICAgICAiI0ZENjQ2NyIKICAgICAgICAgICAgICAgICAgKQoKCgojIHByaW50IGZvciBub3RlYm9vawpoZWFkKGhpc3RvcmljX3NwcCkKYGBgCgoKIyMgUmVndWxhdG9yeSB1bml0cyByZXN1bHQKCmBgYHtyIGNyb3BwZWRfcGxvdF9wYXBlciwgZXZhbCA9IEYsIGVjaG8gPSBUfQoKIyMjIyBEYXRhIG5lZWRlZCAjIyMjCgojIEdldCBzdGF0ZSBvcmRlciBmcm9tIE5vcnRoIHRvIHNvdXRoCnN0YXRlX29yZGVyIDwtIG15X3BhdGgoIkQiLCJTcGF0aWFsL2dyaWRfZWV6X3N3IiwgbmFtZSA9ICJncmlkX2Vlel9zd19kZi5jc3YiLHJlYWQgPSBUKSAlPiUKICBncm91cF9ieShzdGF0ZSkgJT4lIAogIHN1bW1hcmlzZSgKICAgIG9yZGVyID0gbWVhbihsYXQpCiAgKSAlPiUgCiAgbXV0YXRlKGFicmV2ID0gYygiQ1QiLCJERSIsIk1FIiwiTUQiLCJNQSIsIk5IIiwiTkoiLCJOWSIsIk5DIiwiUkkiLCJWQSIpCiAgKSAlPiUgCiAgYXJyYW5nZShkZXNjKG9yZGVyKSkgJT4lIAogIG11dGF0ZShvcmRlcj0gYygiYiIsImEiLGxldHRlcnNbMzoxMV0pKSAlPiUgIyB3ZWlyZGx5IG1haW5lIGdvZXMgYmVsb3cKICBhcnJhbmdlKG9yZGVyKQoKCgojIExvYWQgZ3JpZCBvZiBzdGF0ZSB3YXRlcnMKZ3JpZF9lZXpfc3dfc2YgPC0gIHN0X3JlYWQobXlfcGF0aCgiRCIsIlNwYXRpYWwvZ3JpZF9lZXpfc3ciLCBuYW1lID0gImdyaWRfZWV6X3N3X3NmLnNocCIpKSAlPiUKICBzZWxlY3QoaW5kZXgsc3RhdGUsZ2VvbWV0cnkpICU+JSAKICBtdXRhdGUobWV0aG9kID0gInN0YXRlX3dhdGVycyIsCiAgICAgICAgIHN0YXRlID0gc3RyX3RvX3NlbnRlbmNlKHN0YXRlKSkgJT4lIAogIGxlZnRfam9pbihzdGF0ZV9vcmRlcikKCmdyaWRfZWV6X3N3X3NmJGdyb3VwIDwtIGZhY3RvcihncmlkX2Vlel9zd19zZiRhYnJldiwgICAgICAjIFJlb3JkZXJpbmcgZ3JvdXAgZmFjdG9yIGxldmVscwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gc3RhdGVfb3JkZXIkYWJyZXYpCgoKIyBMb2FkIGdyaWQgb2YgZmlzaGluZyBwb3J0cwpncmlkX2Vlel9mcF9zZiA8LSAgc3RfcmVhZChteV9wYXRoKCJEIiwiU3BhdGlhbC9ncmlkX2Vlel9mcCIsIG5hbWUgPSAiZ3JpZF9lZXpfZnAuc2hwIikpICU+JQogIHNlbGVjdChpbmRleCxhYnJldj1sbmRuZ19zLGdlb21ldHJ5KSAlPiUgCiAgbXV0YXRlKG1ldGhvZCA9ICJmaXNoaW5nX3BvcnQiIywKICAgICAgICAgIyBzdGF0ZSA9IHN0cl90b19zZW50ZW5jZShsYW5kaW5nX3BvcnQpCiAgICAgICAgICklPiUgCiAgbGVmdF9qb2luKHN0YXRlX29yZGVyKQoKCmdyaWRfZWV6X2ZwX3NmJGdyb3VwIDwtIGZhY3RvcihncmlkX2Vlel9mcF9zZiRhYnJldiwgICAgICAjIFJlb3JkZXJpbmcgZ3JvdXAgZmFjdG9yIGxldmVscwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gc3RhdGVfb3JkZXIkYWJyZXYpCgpncmlkX2Vlel9mcF9zZiA8LSBhcnJhbmdlKGdyaWRfZWV6X2ZwX3NmLGdyb3VwKQojIFBsb3R0aW5nIAojIE1ha2Ugc3VyZSBzdF9zaW1wbGlmeSgpIGlzIHJ1biBmb3IgZWV6IHNmCgojIFN0YXRlIHdhdGVycyBwbG90CgpwX3N3IDwtIGdyaWRFeHRyYTo6Z3JpZC5hcnJhbmdlKAogICMgT3ZlcmFsbCAob3ZlcmxhcHBpbmcpIHBvc2l0aW9uCiAgZ2dwbG90KGdyaWRfZWV6X3N3X3NmKSArCiAgICBnZW9tX3NmKGRhdGEgPSBlZXpfc2YsIGFlcygpLCBmaWxsID0gIndoaXRlIikgKyAKICAgIGdlb21fc2YoYWVzKGNvbG9yID1ncm91cCAsIGZpbGwgPSBncm91cCksIGFscGhhID0gMC4zKSArCiAgICBnZW9tX3NmKGRhdGEgPSBsYW5kX3NmLCBhZXMoKSkgKwogICAgZ2dzZmxhYmVsOjpnZW9tX3NmX2xhYmVsX3JlcGVsKGRhdGEgPSBsYW5kX3NmLCBhZXMobGFiZWw9IGFicmV2KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm94LnBhZGRpbmcgPSAwLjEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgICBteV9nZ3RoZW1lX3AobGVnX3BvcyA9ICIiLAogICAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMykgKwogICAgY29vcmRfc2YoeWxpbSA9IGMoMzAsNDgpKSArCiAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygzMCwzNSw0MCw0NSkpKwogICAgbGFicyh4ID0gIiIsIHkgPSAiIiwgdGl0bGUgPSAiQSkgU3RhdGUgd2F0ZXJzIGFwcHJvYWNoIikgKwogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApKSwKICAjIFNob3dpbmcgZWFjaCBzdGF0ZSBzZXBhcmF0ZWx5CiAgZ2dwbG90KGdyaWRfZWV6X3N3X3NmKSArCiAgICBnZW9tX3NmKGRhdGEgPSBsYW5kX3NmLCBhZXMoKSwgZmlsbCA9ICJncmV5ODAiKSArCiAgICBnZW9tX3NmKGFlcyhjb2xvciA9IGdyb3VwKSxzaXplID0gMC4xLCBhbHBoYSA9IDAuMykgKwogICAgZmFjZXRfd3JhcCh+IGdyb3VwKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCwKICAgICAgICAgICAgICAgICAgICAgICAjIGxhYmVscyA9IHVuaXF1ZShncmlkX2Vlel9zd19zZiRncm91cCkpICsKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBncmlkX2Vlel9zd19zZiAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkpICsKICAgIGdndGl0bGUoIiIpICsKICAgIG15X2dndGhlbWVfcChsZWdfcG9zID0gIiIsCiAgICAgICAgICAgICAgICAgYXhfdHhfcyA9IDExLAogICAgICAgICAgICAgICAgIGF4eF90eF9hbmcgPSA0NSwKICAgICAgICAgICAgICAgICBoanVzdCA9IDEKICAgICksCiAgbnJvdyA9IDEpCgoKIyMjIyMgLS0tLS0tLS0tLS0tLSAjIyMjCiMgRmlzaGluZyBQb3J0cyBwbG90CiMjIyMjIC0tLS0tLS0tLS0tLS0gIyMjIwoKCmdyaWRfZWV6X2ZwX3NmIDwtCiAgZ3JpZF9lZXpfc3dfc2YgJT4lIAogIGZpbHRlcighZ3JvdXAgJWluJSBncmlkX2Vlel9mcF9zZiRncm91cCkgJT4lIAogIG11dGF0ZShpbmRleCA9IE5BKSAlPiUgCiAgYmluZF9yb3dzKGdyaWRfZWV6X2ZwX3NmKQogIAogIAoKCnBfZnAgPC0gZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UoCiAgIyBPdmVyYWxsIChvdmVybGFwcGluZykgcG9zaXRpb24KICBnZ3Bsb3QoZGF0YSA9IHN1YnNldChncmlkX2Vlel9mcF9zZiwgaW5kZXggIT0gIk5BIikpICsKICAgIGdlb21fc2YoZGF0YSA9IGVlel9zZiwgYWVzKCksIGZpbGwgPSAid2hpdGUiKSArIAogICAgZ2VvbV9zZihhZXMoY29sb3IgPSBncm91cCwgZmlsbCA9IGFicmV2KSwgYWxwaGEgPSAwLjMpICsKICAgIGdlb21fc2YoZGF0YSA9IGxhbmRfc2YsIGFlcygpKSArCiAgICBnZ3NmbGFiZWw6Omdlb21fc2ZfbGFiZWxfcmVwZWwoZGF0YSA9IGxhbmRfc2YsIGFlcyhsYWJlbD0gYWJyZXYpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib3gucGFkZGluZyA9IDAuMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSArCiAgICAjIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpICsKICAgICMgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhzdGF0ZV9wYWxsZXRbMzo0XSxzdGF0ZV9wYWxsZXRbNjoxM10pKSArCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKHN0YXRlX3BhbGxldFszOjRdLHN0YXRlX3BhbGxldFs2OjEzXSkpICsKICAgIG15X2dndGhlbWVfcChsZWdfcG9zID0gIiIsCiAgICAgICAgICAgICAgICAgYXhfdHhfcyA9IDEzKSArCiAgICBjb29yZF9zZih5bGltID0gYygzMCw0OCkpICsKICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDMwLDM1LDQwLDQ1KSkgKwogICAgbGFicyh4ID0gIiIsIHkgPSAiIiwgdGl0bGUgPSAiQikgRmlzaGluZyBwb3J0cyBhcHByb2FjaCIpICsKICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSksCiAgIyBTaG93aW5nIGVhY2ggc3RhdGUgc2VwYXJhdGVseQogIGdncGxvdCgpICsKICAgIGdlb21fc2YoZGF0YSA9IHN1YnNldChncmlkX2Vlel9mcF9zZiwgaW5kZXggPSAiTkEiKSwgY29sb3IgPSAid2hpdGUiKSArCiAgICBnZW9tX3NmKGRhdGEgPSBzdWJzZXQoZ3JpZF9lZXpfZnBfc2YsIGluZGV4ICE9ICJOQSIpLCBhZXMoY29sb3IgPSBncm91cCksc2l6ZSA9IDAuMSwgYWxwaGEgPSAwLjMpICsKICAgIGdlb21fc2YoZGF0YSA9IGxhbmRfc2YsIGFlcygpLCBmaWxsID0gImdyZXk4MCIpICsKICAgIGZhY2V0X3dyYXAofiBncm91cCkgKwogICAgZ2VvbV9wb2ludChkYXRhID0gcmVuYW1lKHBvcnRzX2RmLCBncm91cCA9IGxhbmRpbmdfc3RhdGUpLCBhZXMoeCA9IGxvbiwgeSA9IGxhdCksIGNvbG9yID0gIiNFNkEwQzQiKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKwogICAgIyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoc3RhdGVfcGFsbGV0WzM6NF0sc3RhdGVfcGFsbGV0WzY6MTNdKSwKICAgICAgICAgICAgICAgICAgICAgICAjIGxhYmVscyA9IHVuaXF1ZShncmlkX2Vlel9mcF9zZiRncm91cCkpICsKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBncmlkX2Vlel9mcF9zZiAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkpICsKICAgIGdndGl0bGUoIiIpICsKICAgIG15X2dndGhlbWVfcChsZWdfcG9zID0gIiIsCiAgICAgICAgICAgICAgICAgYXhfdHhfcyA9IDExLAogICAgICAgICAgICAgICAgIGF4eF90eF9hbmcgPSA0NSwKICAgICAgICAgICAgICAgICBoanVzdCA9IDEKICAgICksCiAgbnJvdyA9IDEpCgoKCmNvbWJpbmVkX3Bsb3QgPC0gZ3JpZEV4dHJhOjpncmlkLmFycmFuZ2UocF9zdyxwX2ZwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9ICJMb25naXR1ZGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQgPSAiTGF0aXR1ZGUiKQoKZ2dzYXZlKGZpbGVuYW1lID0gImJ1ZmZlcl9maWd1cmUuanBnIiwKICAgICAgIHBsb3QgPSBjb21iaW5lZF9wbG90LAogICAgICAgcGF0aCA9IG15X3BhdGgoIlIiLCJGaWd1cmVzIiksCiAgICAgICB3aWR0aCA9IDExLAogICAgICAgaGVpZ2h0ID0gMTEKICAgICAgICkKCmBgYAoKIyMgSW50ZXJwb2xhdGlvbiByZXN1bHQKCmBgYHtyfQoKIyBJbnRlcnBvbGF0aW9uIGRhdGEKaW50ZXJwb2xfcmVzdWx0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZmlsdGVyKCFpcy5uYShsYWJlbCkpICU+JSAKICBncm91cF9ieShsYWJlbCxpbmRleCxzcHAsc2Vhc29uLGxhdCxsb24pICU+JSAKICBzdW1tYXJpc2UobWVhbl9jcHVlID0gbWVhbih2YWx1ZSxuYS5ybT1UKSkgJT4lIAogIGZpbHRlcighaXMubmEobWVhbl9jcHVlKSkKCgojIFBhcGVyIG51bWJlcnMKCiMgaW50ZXJwb2xfcmVzdWx0ICU+JSAKIyAgIGZpbHRlcihtZWFuX2NwdWUgPjApICU+JSAKIyAgIFZpZXcoKQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwojIEJpb21hc3MgQ2VudHJvaWQgc2hpZnQKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKIyBFc3RpbWF0ZSB0b3RhbCBpbnRlcnBvbGF0aW9uCnRvdGFsX2ludGVyIDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZmlsdGVyKCFpcy5uYShsYWJlbCkpICU+JSAKICBncm91cF9ieShzcHAsaW5kZXgsc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fY3B1ZSA9IG1lYW4odmFsdWUsbmEucm09VCkpICU+JSAKICBncm91cF9ieShzcHAsc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsX2NwdWUgPSBzdW0obWVhbl9jcHVlLCBuYS5ybSA9IFQpKQoKCiMgRXN0aW1hdGUgY2VudHJvaWQgYmFzZWQgb24gdG9wIDEwIGdyaWRzIHdpdGggaGlnZXIgYWJ1bmRhbmNlCmNlbnRyb2lkX2RiIDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZmlsdGVyKCFpcy5uYShsYWJlbCkpICU+JSAKICBncm91cF9ieShsYWJlbCxpbmRleCxzcHAsc2Vhc29uLGxhdCxsb24pICU+JSAKICBzdW1tYXJpc2UobWVhbl9jcHVlID0gbWVhbih2YWx1ZSxuYS5ybT1UKSkgJT4lIAogIGZpbHRlcighaXMubmEobWVhbl9jcHVlKSkgJT4lIAogIGxlZnRfam9pbih0b3RhbF9pbnRlcikgJT4lIAogIG11dGF0ZSgKICAgIHBlcl9jcHVlID0gcm91bmQoKG1lYW5fY3B1ZS90b3RhbF9jcHVlKSoxMDAsMikKICApICU+JSAKICBncm91cF9ieShzcHAsbGFiZWwsc2Vhc29uKSAlPiUgCiAgdG9wX24oMTAscGVyX2NwdWUpICU+JSAKICBncm91cF9ieShzcHAsbGFiZWwsc2Vhc29uKSAlPiUgCiAgc3VtbWFyaXNlKAogICAgbGF0ID0gbWVhbihsYXQpLAogICAgbG9uID0gbWVhbihsb24pCiAgKQoKIyBQYXBlciBudW1iZXJzCiMgY2VudHJvaWRfZGIgJT4lIAojICAgc2VsZWN0KC1sb24pICU+JSAKIyAgIHNwcmVhZChsYWJlbCxsYXQpICU+JSAKIyAgIG11dGF0ZShkaWZmID0gVG9kYXktUmVmZXJlbmNlKSAlPiUgCiMgICBWaWV3KCkKCgojIEZvciBhbHRlcm5hdGl2ZSBjb2xvciBwYWxsZXQKcGFsIDwtIHdlc19wYWxldHRlKCJaaXNzb3UxIiwxMDAsdHlwZSA9ICJjb250aW51b3VzIikKCmludGVyX21hcCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV90aWxlKGRhdGEgPSBzdWJzZXQoaW50ZXJwb2xfcmVzdWx0LCBtZWFuX2NwdWUgPT0gMCksCiAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICB4ID0gbG9uLAogICAgICAgICAgICAgIHkgPSBsYXQKICAgICAgICAgICAgKSwKICAgICAgICAgICAgZmlsbCA9ICJncmV5OTAiLAogICAgICAgICAgICBjb2xvciA9ICJncmV5OTAiCiAgKSArIAogIGdlb21fdGlsZShkYXRhID0gc3Vic2V0KGludGVycG9sX3Jlc3VsdCwgbWVhbl9jcHVlID4gMCksCiAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICB4ID0gbG9uLAogICAgICAgICAgICAgIHkgPSBsYXQsCiAgICAgICAgICAgICAgZmlsbCA9IGxvZzEwKG1lYW5fY3B1ZSksCiAgICAgICAgICAgICAgY29sb3IgPSBsb2cxMChtZWFuX2NwdWUpCiAgICAgICAgICAgICAgIyBmaWxsID0gbWVhbl9jcHVlLAogICAgICAgICAgICAgICMgY29sb3IgPSBtZWFuX2NwdWUKICAgICAgICAgICAgKQogICkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBjZW50cm9pZF9kYiwKICAgICAgICAgICAgIGFlcygKICAgICAgICAgICAgICAgeCA9IGxvbiwKICAgICAgICAgICAgICAgeSA9IGxhdAogICAgICAgICAgICAgKSwKICAgICAgICAgICAgIHNoYXBlID0gMywKICAgICAgICAgICAgIGNvbG9yID0gIndoaXRlIgogICkgKyAKICBnZW9tX3NmKGRhdGEgPSBsYW5kX3NmLGFlcygpKSArCiAgbGFicyh4ID0gIkxvbmdpdHVkZSIsCiAgICAgICB5ID0gIkxhdGl0dWRlIikgKwogICMgZ2dzZmxhYmVsOjpnZW9tX3NmX2xhYmVsX3JlcGVsKGRhdGEgPSBsYW5kX3NmLCBhZXMobGFiZWw9IGFicmV2KSwgCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gNCwKICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJveC5wYWRkaW5nID0gMC4xMCwKICAjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkgKwogICMgVmlyaWRpcyBvcHRpb24KIyBzY2FsZV9maWxsX3ZpcmlkaXMoIkNQVUUiLAojICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsNDApLAojICAgICAgICAgICAgICAgICAgICAjIGxpbWl0cyA9IGMoLTUsMSksICMgZm9yIGxvZzEwCiMgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IC0xLAojICAgICAgICAgICAgICAgICAgICAgZW5kID0gMC45CiMgICAgICAgICAgICAgICAgICAgICkgKwojIHNjYWxlX2NvbG9yX3ZpcmlkaXMoIkNQVUUiLAojICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygwLDQwKSwKIyAgICAgICAgICAgICAgICAgICAgICMgbGltaXRzID0gYygtNSwxKSwgIyBmb3IgbG9nMTAKIyAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IC0xLAojICAgICAgICAgICAgICAgICAgICAgZW5kID0gMC45CiMgICAgICAgICAgICAgICAgICAgICApICsKIyB3ZXMgYW5kZXJzb24gb3B0aW9uCnNjYWxlX2ZpbGxfZ3JhZGllbnRuKCJDUFVFIiwKICAgICAgICAgICAgICAgICAgICAgY29sb3VycyA9IHBhbCwKICAgICAgICAgICAgICAgICAgICAgIyBsaW1pdHMgPSBjKDAsNDApICMgRm9yIGNwdWUKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygtNSwxKSAjIGZvciBsb2cxMAoKKSArCiAgc2NhbGVfY29sb3JfZ3JhZGllbnRuKCJDUFVFIiwKICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VycyA9IHBhbCwKICAgICAgICAgICAgICAgICAgICAgICAgIyBsaW1pdHMgPSBjKDAsNDApICMgZm9yIGNwdWUKICAgICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygtNSwxKSAjIGZvciBsb2cxMAogICkgKwogIGZhY2V0X2dyaWQoc3BwfnNlYXNvbitsYWJlbCkgKwogIG15X2dndGhlbWVfbShtYXBfdHlwZSA9ICJuYSIsIGxlZ19wb3MgPSAicmlnaHQiLGF4X3R4X3MgPSA3LGF4X3RsX3MgPSAxMCxsZWdfdHhfcyA9IDEyKSAjKwojIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDMsImxpbmUiKSkKCgpnZ3NhdmUoImludGVycG9sYXRpb25fd2EuanBnIiwKICAgICAgIGludGVyX21hcCwKICAgICAgIHBhdGggPSBteV9wYXRoKCJSIiwiRmlndXJlcyIpLAogICAgICAgd2lkdGggPSA5LAogICAgICAgaGVpZ2h0ID0gNykKCmBgYAoKCiMjIEF2ZXJhZ2UgcHJvcG9ydGlvbgoKVGhpcyBtYXAgc2hvd3MgdGhlIGFnZ3JlZ2F0ZWQgZXh0cmFwb2xhdGVkIHZhbHVlIGZyb20gYWxsIHRocmVlIHNwZWNpZXMgcGVyIFN0YXRlIGF2ZXJhZ2UgYWNyb3NzIHRoZSB3aG9sZSBzdHVkeSBwZXJpb2Qgd2l0aGluIGVhY2ggU3RhdGUncyB3YXRlci4KCipOb3RlOiogVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBhIHN1cHBsZW1lbnRhbCBmaWd1cmUKCmBgYHtyIGFyZWFfbWFwX3N0YXRlLCBldmFsID0gVCwgZWNobyA9IFQsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xMn0KCmRhdGFfZ3JpZCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHN0YXRlLGxhdCxsb24scmVnaW9uLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2Uoc3VtID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lICMgc3VtIG9mIGFsbCBzcGVjaWVzCiAgZ3JvdXBfYnkoc3RhdGUsbGF0LGxvbixyZWdpb24sc3BhdGlhbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuID0gbWVhbihzdW0sbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAjIGF2ZXJhZ2Ugb2YgYWxsIHllYXJzCgoKZ2dwbG90KGRhdGEgPSBzdWJzZXQoZGF0YV9ncmlkLCAhaXMubmEobWVhbikpKSArCiAgZ2VvbV90aWxlKAogICAgYWVzKAogICAgICB4ID0gbG9uLAogICAgICB5ID0gbGF0LAogICAgICBmaWxsID0gbWVhbiwKICAgICAgY29sID0gbWVhbgogICAgKQogICkgKwogIGdlb21fc2YoZGF0YSA9IGxhbmRfc2YsIGFlcygpKSArCiAgZmFjZXRfd3JhcCh+IHN0YXRlICArICByZWdpb24gKyBzcGF0aWFsKSArCiAgbGFicyh4ID0gIkxvbmdpdHVkZSIsIHkgPSAiTGF0aXR1ZGUiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzKCJNZWFuIEludGVycG9sYXRpb24iLCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoIk1lYW4gSW50ZXJwb2xhdGlvbiIsIGFscGhhID0gMC44KSArCiAgdGhlbWVfYncoKQpgYGAKCiMjIFByb3BvcnRpb24gQ2hhbmdlCgpIZXJlIHdlIHNob3cgdGhlIGF2ZXJhZ2UgcHJvcG9ydGlvbiBvZiB0aGUgaW50ZXJwb2xhdGlvbiBieSBTdGF0ZSBhbmQgdGltZSBwZXJpb2QuIFRpbWUgcGVyaW9kcyB3ZXJlIGFyYml0cmFyeSBkZWZpbmVkIGFzOwoKLSBFYXJseTsgMTk3MyB0byAxOTg0Ci0gTWlkOyAxOTg1IHRvIDE5OTcKLSBMYXRlOyAxOTk4IHRvIDIwMTEKLSBOb3c7IDIwMTIgdG8gMjAxOQoKKk5vdGVzOiogRmlndXJlIHJlcHJlc2VudHMgdGhlICoqU3ByaW5nKiogc3VydmV5LiBUaGlzIGNvbXB1dGF0aW9uIGNvbnNpZGVycyB0aGUgT3ZlcmxhcHBpbmcgb2Ygc3RhdGUgd2F0ZXJzLgoKIyMjIERhdGEgcHJlcGFyYXRpb24KCmBgYHtyIGRhdGFfcHJlcCwgZXZhbCA9IEYsIGVjaG8gPSBULCByZXN1bHRzPSdoaWRlJ30KCgp0b3RhbF9maXRlZCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHllYXIsc2Vhc29uLHNwcCxzcGF0aWFsKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPVQpLC5ncm91cHMgPSAiZHJvcCIpCgoKc3RhdGVfZml0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixsYWJlbCxzZWFzb24sc3BwLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2Uoc3RhdGVfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgIyBWaWV3KCkKICBsZWZ0X2pvaW4odG90YWxfZml0ZWQsCiAgICAgICAgICAgIGJ5ID0gYygieWVhciIsInNlYXNvbiIsInNwcCIsInNwYXRpYWwiKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDApICU+JSAKICBncm91cF9ieShzdGF0ZSxsYWJlbCxzZWFzb24sc3BwLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9wZXIgPSByb3VuZChtZWFuKHBlcmNlbnRhZ2UpKSwuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgI09ubHkgc2hvdyByZXN1bHRzIGZvciBzcHJpbmcKICBmaWx0ZXIoIWlzLm5hKGxhYmVsKSkKCmBgYAoKIyMjIyBSZWd1bGF0b3J5IHVuaXRzIG1hcAoKYGBge3IgcmVnX3VuaXRfbWFwX2RpZmYsIGV2YWwgPSBGLCBlY2hvID0gVCwgcmVzdWx0cz0naGlkZSd9CgpyZWdfdW5pdCA8LSBzdGF0ZV9maXQgJT4lIAogIGZpbHRlcihzZWFzb24gPT0gIlNwcmluZyIpICU+JSAKICBzcHJlYWQoc3BhdGlhbCxtZWFuX3BlcikgJT4lIAogICMgU2V0IE5BJ3MgdG8gMCBiZWNhdXNlIG5vIGRhdGEgZm91bmQgb24gRlAKICBtdXRhdGUoZnAgPSByZXBsYWNlX25hKGZwLDApKSAlPiUgCiAgIyBWaWV3KCkKICBtdXRhdGUoCiAgICBkaWZmZXJlbmNlID0gYWJzKGZwLXN3KSwKICAgIGRpZmZlcmVuY2UgPSBpZmVsc2UoZGlmZmVyZW5jZSA+IDEwMCwxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShkaWZmZXJlbmNlIDwgLTEwMCwtMTAwLGRpZmZlcmVuY2UpCiAgICApCiAgKSAlPiUgCiAgZ2F0aGVyKCJzcGF0aWFsIiwibWVhbl9wZXIiLGZwOmRpZmZlcmVuY2UpICU+JSAKICBtdXRhdGUoc3BwID0gZ3N1YigiICIsIlxuIixzcHApLAogICAgICAgICBzcGF0aWFsID0gaWZlbHNlKHNwYXRpYWwgPT0gImZwIiwiRmlzaGluZyBwb3J0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHNwYXRpYWwgPT0gInN3IiwiU3RhdGUgd2F0ZXJzIiwiRGlmZmVyZW5jZSIpCiAgICAgICAgICkKICApCgoKIyBUaGUgcGxvdAptYXBfcGxvdCA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4ocmVnX3VuaXQsCiAgICAgICAgICAgIGJ5ID0gInN0YXRlIikgJT4lIAogIGZpbHRlcihzcGF0aWFsICE9ICJEaWZmZXJlbmNlIikgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gbWVhbl9wZXIpKSArCiAgdmlyaWRpczo6c2NhbGVfZmlsbF92aXJpZGlzKCJBdmVyYWdlIHByb3BvcnRpb24gcGVyIFN0YXRlIiwgYWxwaGEgPSAwLjgsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCwzNSw1KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXRzPShjKDAsMzUpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKwogIGZhY2V0X2dyaWQoc3BhdGlhbH4gc3BwK2xhYmVsKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICIiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAyMCwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICJib3R0b20iLAogICAgICAgICAgICAgICBheHhfdHhfYW5nID0gNDUsCiAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMiwKICAgICAgICAgICAgICAgYXhfdGxfcyA9IDE4LAogICAgICAgICAgICAgICBoanVzdCA9IDEpICsKICB0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCg0LCJsaW5lIikpIAoKCmRpZmZfcGxvdCA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4ocmVnX3VuaXQsCiAgICAgICAgICAgIGJ5ID0gInN0YXRlIikgJT4lIAogIGZpbHRlcihzcGF0aWFsID09ICJEaWZmZXJlbmNlIikgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gbWVhbl9wZXIpKSArCiAgdmlyaWRpczo6c2NhbGVfZmlsbF92aXJpZGlzKCJEaWZmZXJlbmNlICglKSIsIGFscGhhID0gMC44LG9wdGlvbiA9ICJDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsMjAsNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cz0oYygwLDIyKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbGFiZWxzID0gYygiPC0xMCIsc2VxKC03NSw3NSwyNSksIj4xMDAiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsKICBmYWNldF9ncmlkKHNwYXRpYWx+IHNwcCtsYWJlbCkgKwogIGxhYnMoeCA9ICIiLCAKICAgICAgIHkgPSAiIikgKwogIG15X2dndGhlbWVfcChmYWNldF90eF9zID0gMjAsCiAgICAgICAgICAgICAgIGxlZ19wb3MgPSAiYm90dG9tIiwKICAgICAgICAgICAgICAgYXh4X3R4X2FuZyA9IDQ1LAogICAgICAgICAgICAgICBheF90eF9zID0gMTIsCiAgICAgICAgICAgICAgIGF4X3RsX3MgPSAxOCwKICAgICAgICAgICAgICAgaGp1c3QgPSAxKSArCiAgdGhlbWUobGVnZW5kLmtleS53aWR0aCA9IHVuaXQoNCwibGluZSIpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgKSAKCgojIENvd3Bsb3Qgb3B0aW9uCnAgPC0gZ2dkcmF3KCkgKwogICMgUmV2ZW51ZSBjaXJjdWxhcgogIGRyYXdfcGxvdChtYXBfcGxvdCwgeCA9IDAsIHkgPSAwLjIsIHdpZHRoID0gMSwgaGVpZ2h0ID0gMC44KSArCiAgIyBDYXRjaCBjaXJjdWxhcgogIGRyYXdfcGxvdChkaWZmX3Bsb3QsIHggPSAwLCB5ID0gMCwgd2lkdGggPSAxLCBoZWlnaHQgPSAwLjQpICsKICBkcmF3X3Bsb3RfbGFiZWwobGFiZWwgPSBjKCJMYXRpdHVkZSIsICJMb25naXR1ZGUiKSwgCiAgICAgICAgICAgICAgICAgIHNpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgYW5nbGUgPSBjKDkwLDApLAogICAgICAgICAgICAgICAgICB4ID0gYygwLDAuNDUpLCAKICAgICAgICAgICAgICAgICAgeSA9IGMoMC40NSwwLjE1KQogICkKICAKCnNhdmVfcGxvdCgKICBwYXRoID0gbXlfcGF0aCgiUiIsIkZpZ3VyZXMiKSwKICAicHJvcG9ydGlvbl9jaGdfcmVnLmpwZyIsCiAgcCwKICBiYXNlX2hlaWdodCA9IDE0LAogIGJhc2Vfd2lkdGggPSAxNAopCgpyZWdfdW5pdCAlPiUgCiAgIyBmaWx0ZXIoc3BhdGlhbCA9PSAiZnAiKSAlPiUKICBzZWxlY3QoLWZwKSAlPiUgCiAgc3ByZWFkKGxhYmVsLHN3KSAlPiUgCiAgbXV0YXRlKAogICAgZGlmZmVyZW5jZSA9IFRvZGF5LVJlZmVyZW5jZQogICAgKSAlPiUgCiAgZ3RoZXIoUmVmZXJlbmNlOmRpZmZlcmVuY2UpCgpgYGAKCiMjIyMgU2Vhc29uYWwgdW5pdHMgbWFwCgpgYGB7ciBzZWFfdW5pdF9tYXBfZGlmZiwgZXZhbCA9IEYsIGVjaG8gPSBULCByZXN1bHRzPSdoaWRlJ30KCiMgR2V0IHNlYXNvbmFsIGRhdGEKc2Vhc29uX2ZpdCA8LSBzdGF0ZV9maXQgJT4lIAogIGZpbHRlcihzcGF0aWFsICE9ICJmcCIpICU+JQogIHNwcmVhZChzZWFzb24sbWVhbl9wZXIpICU+JQogIG11dGF0ZSgKICAgIERpZmZlcmVuY2UgPSBhYnMoRmFsbC1TcHJpbmcpLAogICAgRGlmZmVyZW5jZSA9IGlmZWxzZShEaWZmZXJlbmNlID4gMTAwLDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERpZmZlcmVuY2UgPCAtMTAwLC0xMDAsRGlmZmVyZW5jZSkKICAgICkKICApICU+JSAKICBnYXRoZXIoInNlYXNvbiIsIm1lYW5fcGVyIixGYWxsOkRpZmZlcmVuY2UpICU+JSAKICBtdXRhdGUoc3BwID0gZ3N1YigiICIsIlxuIixzcHApKQoKIyBUaGUgcGxvdAptYXBfcGxvdCA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4oc2Vhc29uX2ZpdCwKICAgICAgICAgICAgYnkgPSAic3RhdGUiKSAlPiUgCiAgZmlsdGVyKHNlYXNvbiAhPSAiRGlmZmVyZW5jZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IG1lYW5fcGVyKSkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcygiQXZlcmFnZSBwcm9wb3J0aW9uIHBlciBTdGF0ZSIsIGFscGhhID0gMC44LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKDAsMTUsNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cz0oYygwLDE1KSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSsKICBmYWNldF9ncmlkKHNlYXNvbn4gc3BwK2xhYmVsKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICIiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAyMCwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICJib3R0b20iLAogICAgICAgICAgICAgICBheHhfdHhfYW5nID0gNDUsCiAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMiwKICAgICAgICAgICAgICAgYXhfdGxfcyA9IDE4LAogICAgICAgICAgICAgICBoanVzdCA9IDEpICsKICB0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCg0LCJsaW5lIikpIAoKCmRpZmZfcGxvdCA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4oc2Vhc29uX2ZpdCwKICAgICAgICAgICAgYnkgPSAic3RhdGUiKSAlPiUgCiAgZmlsdGVyKHNlYXNvbiA9PSAiRGlmZmVyZW5jZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IG1lYW5fcGVyKSkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcygiRGlmZmVyZW5jZSAoJSkiLCBhbHBoYSA9IDAuOCxvcHRpb24gPSAiQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgwLDUsMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cz0oYygwLDUpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBsYWJlbHMgPSBjKCI8LTEwIixzZXEoLTc1LDc1LDI1KSwiPjEwMCIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgKwogIGZhY2V0X2dyaWQoc2Vhc29ufiBzcHArbGFiZWwpICsKICBsYWJzKHggPSAiIiwgCiAgICAgICB5ID0gIiIpICsKICBteV9nZ3RoZW1lX3AoZmFjZXRfdHhfcyA9IDIwLAogICAgICAgICAgICAgICBsZWdfcG9zID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgIGF4eF90eF9hbmcgPSA0NSwKICAgICAgICAgICAgICAgYXhfdHhfcyA9IDEyLAogICAgICAgICAgICAgICBheF90bF9zID0gMTgsCiAgICAgICAgICAgICAgIGhqdXN0ID0gMSkgKwogIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDQsImxpbmUiKSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKQogICAgICAgICkgCgoKIyBDb3dwbG90IG9wdGlvbgpwIDwtIGdnZHJhdygpICsKICAjIFJldmVudWUgY2lyY3VsYXIKICBkcmF3X3Bsb3QobWFwX3Bsb3QsIHggPSAwLCB5ID0gMC4yLCB3aWR0aCA9IDEsIGhlaWdodCA9IDAuOCkgKwogICMgQ2F0Y2ggY2lyY3VsYXIKICBkcmF3X3Bsb3QoZGlmZl9wbG90LCB4ID0gMCwgeSA9IDAsIHdpZHRoID0gMSwgaGVpZ2h0ID0gMC40KSArCiAgZHJhd19wbG90X2xhYmVsKGxhYmVsID0gYygiTGF0aXR1ZGUiLCAiTG9uZ2l0dWRlIiksIAogICAgICAgICAgICAgICAgICBzaXplID0gMTgsCiAgICAgICAgICAgICAgICAgIGFuZ2xlID0gYyg5MCwwKSwKICAgICAgICAgICAgICAgICAgeCA9IGMoMCwwLjQ1KSwgCiAgICAgICAgICAgICAgICAgIHkgPSBjKDAuNDUsMC4xNSkKICApCiAgCgpzYXZlX3Bsb3QoCiAgcGF0aCA9IG15X3BhdGgoIlIiLCJGaWd1cmVzIiksCiAgInByb3BvcnRpb25fY2hnX3NlYXNfLmpwZyIsCiAgcCwKICBiYXNlX2hlaWdodCA9IDE0LAogIGJhc2Vfd2lkdGggPSAxNAopCgpgYGAKCiMjIEFyZWEgcGxvdAoKVGhpcyBncmFwaCBzaG93cyB0aGUgcHJvcG9ydGlvbiBvZiB0aGUgaW50ZXJwb2xhdGlvbiB2YWx1ZSBlYWNoIFN0YXRlIGhhcyBvdmVyIHRpbWUuCgoqTm90ZToqIFRoaXMgcGxvdCBpcyBpbnRlcmFjdGl2ZS4gRm9yIGVhc2UgY29tcGFyaXNvbiBiZXR3ZWVuIFN0YXRlcyB5b3UgY2FuOwoKLSAqT25lKiBjbGljayBvbiBhbnkgU3RhdGUgdG8gKnJlbW92ZSogaXQgZnJvbSB0aGUgcGxvdCAKLSAqVHdvKiBjbGlja3Mgb24gYW55IFN0YXRlIHRvICppc29sYXRlIGl0KiBmcm9tIHRoZSBwbG90IChvdGhlciBzdGF0ZXMgY2FuIHRoZW4gYmUgYWRkZWQgYnkganVzdCBjbGlja2luZyBvbiB0aGVtKS4KLSBUaGUgYm90dG9tIHBhbmVsIGFsbG93cyB5b3UgdG8gcmVkdWNlIHRoZSB0aW1lIGZyYW1lCgojIyMgRHluYW1pYyBhZ2dyZWdhdGVkIHBsb3QKCmBgYHtyIGR5bmFtaWNfYXJlYV9wbG90LCBldmFsID0gVCwgZWNobyA9IFQsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTB9Cgp0b3RhbF9maXRlZCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHllYXIscmVnaW9uKSAlPiUgCiAgc3VtbWFyaXNlKHRvdGFsX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPVQpLC5ncm91cHMgPSAiZHJvcCIpCgojIGdyb3VwIGJ5IHN0YXRlCnN0YXRlX2ZpdCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHllYXIscmVnaW9uKSAlPiUgCiAgc3VtbWFyaXNlKHN0YXRlX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGxlZnRfam9pbih0b3RhbF9maXRlZCwKICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwicmVnaW9uIikpICU+JQogIG11dGF0ZShwZXJjZW50YWdlID0gc3RhdGVfdmFsdWUvdG90YWxfdmFsdWUqMTAwKQoKIyBQbG90IG1lCnAgPC0gZ2dwbG90KHN0YXRlX2ZpdCkgKwogIGdlb21fYXJlYSgKICAgIGFlcygKICAgICAgeCA9IHllYXIsCiAgICAgIHkgPSByb3VuZChwZXJjZW50YWdlKSwKICAgICAgZmlsbCA9IHN0YXRlCiAgICApCiAgKSArCiAgeWxhYigiUGVyY2VudGFnZSAoJSkiKSArCiAgIyB2aXJpZGlzOjpzY2FsZV9maWxsX3ZpcmlkaXMoZGlzY3JldGUgPSBULCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHN0YXRlX3BhbGxldCkgKwogIE15RnVuY3Rpb25zOjpteV9nZ3RoZW1lX3AoKSArCiAgZmFjZXRfd3JhcCh+cmVnaW9uLCBuY29sID0gMSkgKwogIHRoZW1lX2RhcmsoKQoKZ2dwbG90bHkocCwKICAgICAgICAgZHluYW1pY1RpY2tzID0gVFJVRSkgJT4lIAogIGxheW91dChob3Zlcm1vZGUgPSAieCIpICU+JQogIHJhbmdlc2xpZGVyKCkKCmBgYAoKIyMgQXJlYSBwbG90IChydW5uaW5nIG1lYW4pCgpUaGlzIGdyYXBoIHNob3dzIHRoZSBwcm9wb3J0aW9uIG9mIGVhY2ggU3RhdGUgc21vb3RoZWQgb3ZlciBhICoxMCB5ZWFycyBydW5uaW5nIG1lYW4qKi4gSXQgYWxsb3dzIHRvIGJldHRlciBzZWUgaW5jcmVhc2luZyBhbmQgZGVjcmVhc2luZyB0cmVuZHMuCgojIyMgRHluYW1pYyBhZ2dyZWdhdGVkIHBsb3QKCipOb3RlOiogVGhpcyBwbG90IGlzIGFsc28gaW50ZXJhY3RpdmUgYW5kIHRodXMsIGZvbGxvd3MgdGhlIHNhbWUgb3B0aW9ucyBvZiB0aGUgcHJldmlvdXMgb25lLgoKYGBge3IgYXJlYV9wbG90LCBldmFsID0gVCwgZWNobyA9IFQsIGZpZy5oZWlnaHQgPSAxMCwgZmlnLndpZHRoID0gMTB9CgojIGdyb3VwIGJ5IHN0YXRlCnN0YXRlX2ZpdCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHllYXIscmVnaW9uLC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICBzdW1tYXJpc2Uoc3RhdGVfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgbGVmdF9qb2luKHRvdGFsX2ZpdGVkLAogICAgICAgICAgICBieSA9IGMoInllYXIiLCJyZWdpb24iKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDApICU+JSAKICBncm91cF9ieShzdGF0ZSxyZWdpb24pICU+JSAKICBtdXRhdGUoUk1lYW4gPSB6b286OnJvbGxtZWFuKHggPSBwZXJjZW50YWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm09VCkKICAgICkgJT4lICAKICBsZWZ0X2pvaW4oc3RhdGVfbGF0KQoKIyBQbG90IG1lCnAgPC0gZ2dwbG90KHN0YXRlX2ZpdCkgKwogIGdlb21fYXJlYSgKICAgIGFlcygKICAgICAgeCA9IHllYXIsCiAgICAgIHkgPSByb3VuZChSTWVhbiksCiAgICAgIGZpbGwgPSBzdGF0ZQogICAgICAjIGZpbGwgPSBvcmRlcgogICAgKQogICkgKwogIHlsYWIoIjEwIHlycyBydW5uaW5nIGF2ZXJhZ2UgKCUpIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKAogICAgIlN0YXRlIiwKICAgIHZhbHVlcyA9IHN0YXRlX3BhbGxldCwKICAgICMgbGFiZWxzID0gc3RhdGVfZml0ICU+JSBhcnJhbmdlKG9yZGVyKSAlPiUgIHB1bGwoc3RhdGUpICU+JSB1bmlxdWUoKQogICkgKwogIE15RnVuY3Rpb25zOjpteV9nZ3RoZW1lX3AoKSArCiAgZmFjZXRfd3JhcCh+cmVnaW9uLCBuY29sID0gMSkgKwogIHRoZW1lX2RhcmsoKQoKc3VwcHJlc3NXYXJuaW5ncygKZ2dwbG90bHkocCwKICAgICAgICAgZHluYW1pY1RpY2tzID0gVFJVRSkgJT4lIAogIGxheW91dChob3Zlcm1vZGUgPSAieCIpICU+JSAKICAjIGFkZF90cmFjZSgpICU+JSAKICByYW5nZXNsaWRlcigpCikKCmBgYAoKIyMjIEFnZ3JlZ2F0ZWQgUHJvcG9ydGlvbmFsIGNoYW5nZQoKYGBge3IgcGxvdF9hcmVhX2F2ZV9hZ2csIGV2YWwgPSBGLCBlY2hvID0gRiwgcmVzdWx0cz0naGlkZSd9Cgp0b3RhbF9maXRlZCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHllYXIscmVnaW9uLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2UodG90YWxfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09VCksLmdyb3VwcyA9ICJkcm9wIikKCgojIGdyb3VwIGJ5IHN0YXRlCnN0YXRlX2ZpdCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHllYXIscmVnaW9uLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2Uoc3RhdGVfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgbGVmdF9qb2luKHRvdGFsX2ZpdGVkLAogICAgICAgICAgICBieSA9IGMoInllYXIiLCJyZWdpb24iLCJzcGF0aWFsIikpICU+JQogIG11dGF0ZShwZXJjZW50YWdlID0gc3RhdGVfdmFsdWUvdG90YWxfdmFsdWUqMTAwKSAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUscmVnaW9uLHNwYXRpYWwpICU+JSAKICBtdXRhdGUoUk1lYW4gPSB6b286OnJvbGxtZWFuKHggPSBwZXJjZW50YWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmEucm09VCkKICAgICkgJT4lIAogICNPbmx5IHNob3cgcmVzdWx0cyBmb3Igc3ByaW5nCiAgZmlsdGVyKHN0cl9kZXRlY3QocmVnaW9uLCJTcHJpbmciKSwKICAgICAgICAgIWlzLm5hKFJNZWFuKSAjIFJlbW92ZSBOQXMgZnJvbSByb2xsbWVhbgogICAgICAgICApICU+JSAgCiAgbGVmdF9qb2luKHN0YXRlX2xhdCkgJT4lIAogIG11dGF0ZSgKICAgICAgICAgc3BhdGlhbCA9IGlmZWxzZShzcGF0aWFsID09ICJmcCIsIkZpc2hpbmcgcG9ydHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShzcGF0aWFsID09ICJzdyIsIlN0YXRlIFdhdGVycyIsIkRpZmZlcmVuY2UiKQogICAgICAgICApCiAgKQoKCiMgUGxvdCBtZQphZ2dfYXJlYSA8LSBnZ3Bsb3Qoc3RhdGVfZml0KSArCiAgZ2VvbV9hcmVhKAogICAgYWVzKAogICAgICB4ID0geWVhciwKICAgICAgeSA9IHJvdW5kKFJNZWFuKSwKICAgICAgZmlsbCA9IG9yZGVyCiAgICAgICMgZmlsbCA9IHN0YXRlCiAgICApCiAgKSArCiAgYW5ub3RhdGUoZ2VvbT0gInJlY3QiLAogICAgICAgICAgIHhtaW4gPSAxOTgwLCB4bWF4ID0gMjAwMSwgCiAgICAgICAgICAgeW1pbiA9IDAsIHltYXggPSAxMDAsCiAgICAgICAgICAgIGZpbGwgPSAiZ3JheTkwIiwKICAgICAgICAgICBjb2xvdXIgPSBOQSwKICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIHlsYWIoIlByb3BvdGlvbiAoMTAgeXJzIHJ1bm5pbmcgYXZlcmFnZSkiKSArCiAgIyB2aXJpZGlzOjpzY2FsZV9maWxsX3ZpcmlkaXMoZGlzY3JldGUgPSBULCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKAogICAgIlN0YXRlXG4oTGF0aXR1ZGluYWwgb3JkZXIpIiwKICAgIHZhbHVlcyA9IHN0YXRlX3BhbGxldCwKICAgIGxhYmVscyA9IHN0YXRlX2ZpdCAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkKICApICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDE5NzksMjAxNSw5KSxsaW1pdHMgPSBjKDE5NzksMjAxNSkpKwogIHhsYWIoIlllYXIiKSArCiAgbXlfZ2d0aGVtZV9wKGxlZ19wb3MgPSAicmlnaHQiLCBoanVzdCA9IDEsYXhfdHhfcyA9IDEwLGxlZ190eF9zID0gMTAsIGxlZ190bF9zID0gMTIsYXhfdGxfcyA9IDEyKSArCiAgdGhlbWUobGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMSwibGluZSIpLAogICAgICAgIGxlZ2VuZC50aXRsZS5hbGlnbj0wLjUpICsKICBmYWNldF93cmFwKH5zcGF0aWFsKSAKCgogICAgZ2dzYXZlKGZpbGVuYW1lID0gImFyZWFfcGxvdF9hdmdfYWdnX3NwdGwuanBnIiwKICAgICAgICAgcGxvdCA9IGFnZ19hcmVhLAogICAgICAgICBwYXRoID0gbXlfcGF0aCgiUiIsIkZpZ3VyZXMiKSwKICAgICAgICAgd2lkdGggPSA4LAogICAgICAgICBoZWlnaHQgPSA2CiAgICAgICAgICkKCgpgYGAKCiMjIyBQYXBlciBmaWd1cmU6IFBlciBTcGVjaWVzIFByb3BvcnRpb25hbCBjaGFuZ2UKCmBgYHtyIHBhcGVyX3Bsb3RfYXJlYV9hdmVfc3BwLCBldmFsID0gRiwgZWNobyA9IEYsIHJlc3VsdHM9J2hpZGUnfQoKdG90YWxfZml0ZWQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieSh5ZWFyLHJlZ2lvbixzcHAsc3BhdGlhbCkgJT4lIAogIHN1bW1hcmlzZSh0b3RhbF92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT1UKSwuZ3JvdXBzID0gImRyb3AiKQoKCiMgZ3JvdXAgYnkgc3RhdGUKc3RhdGVfZml0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixsYWJlbCxyZWdpb24sc3BwLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2Uoc3RhdGVfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09IFQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgbGVmdF9qb2luKHRvdGFsX2ZpdGVkLAogICAgICAgICAgICBieSA9IGMoInllYXIiLCJyZWdpb24iLCJzcHAiLCJzcGF0aWFsIikpICU+JQogIG11dGF0ZShwZXJjZW50YWdlID0gc3RhdGVfdmFsdWUvdG90YWxfdmFsdWUqMTAwKSAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUscmVnaW9uLHNwcCxzcGF0aWFsKSAlPiUgCiAgbXV0YXRlKFJNZWFuID0gem9vOjpyb2xsbWVhbih4ID0gcGVyY2VudGFnZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtPVQpCiAgICApICU+JSAKICAjT25seSBzaG93IHJlc3VsdHMgZm9yIHNwcmluZwogIGZpbHRlcihzdHJfZGV0ZWN0KHJlZ2lvbiwiU3ByaW5nIiksCiAgICAgICAgICFpcy5uYShSTWVhbikgIyBSZW1vdmUgTkFzIGZyb20gcm9sbG1lYW4KICAgICAgICAgKSAlPiUgIAogIGxlZnRfam9pbihzdGF0ZV9sYXQpICU+JSAKICBtdXRhdGUoCiAgICAgICAgIHNwYXRpYWwgPSBpZmVsc2Uoc3BhdGlhbCA9PSAiZnAiLCJGaXNoaW5nIHBvcnRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uoc3BhdGlhbCA9PSAic3ciLCJTdGF0ZSB3YXRlcnMiLCJEaWZmZXJlbmNlIikKICAgICAgICAgKQogICkKCgojIFNoYWRlZCBwZXJpb2QgCmhpc3RvcmljX3BlcmlvZHMgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBmaWx0ZXIobGFiZWwgPT0gIlJlZmVyZW5jZSIpICU+JSAKICBncm91cF9ieShzcHAsbGFiZWwseWVhcikgJT4lIAogIHN1bW1hcmlzZShuID0gbigpLW4oKSsxMDApICU+JSAKICBtdXRhdGUocGVyaW9kID0gIlJlZmVyZW5jZSBwZXJpb2QiKQoKCiMgUGxvdCBtZQpzc3BfYXJlYSA8LQogIGdncGxvdChzdGF0ZV9maXQpICsKICBnZW9tX2FyZWEoCiAgICBhZXMoCiAgICAgIHggPSB5ZWFyLAogICAgICB5ID0gcm91bmQoUk1lYW4pLAogICAgICBmaWxsID0gb3JkZXIKICAgICAgIyBmaWxsID0gc3RhdGUKICAgICkKICApICsKICBnZW9tX2FyZWEoZGF0YSA9IGhpc3RvcmljX3BlcmlvZHMsCiAgICAgICAgICAgICBhZXMoCiAgICAgICAgICAgICAgIHggPSB5ZWFyLAogICAgICAgICAgICAgICB5ID0gbiwKICAgICAgICAgICAgICAgY29sb3IgPSBwZXJpb2QKICAgICAgICAgICAgICksCiAgICAgICAgICAgICAjIGZpbGwgPSAiZ3JheTkwIiwKICAgICAgICAgICAgIGFscGhhID0gMC4zLAogICAgICAgICAgICBzdGF0ID0gImlkZW50aXR5IgogICAgICAgICAgICAgKSArCiAgIyBhbm5vdGF0ZShnZW9tPSAicmVjdCIsCiAgIyAgICAgICAgICB4bWluID0gMTk4MCwgeG1heCA9IDIwMDEsIAogICMgICAgICAgICAgeW1pbiA9IDAsIHltYXggPSAxMDAsCiAgIyAgICAgICAgICAgZmlsbCA9ICJncmF5OTAiLAogICMgICAgICAgICAgY29sb3VyID0gTkEsCiAgIyAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIHlsYWIoIlByb3BvdGlvbiAoMTAgeXJzIHJ1bm5pbmcgYXZlcmFnZSkiKSArCiAgIyB2aXJpZGlzOjpzY2FsZV9maWxsX3ZpcmlkaXMoZGlzY3JldGUgPSBULCBhbHBoYSA9IDAuOCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKAogICAgIlN0YXRlXG4oTGF0aXR1ZGluYWwgb3JkZXIpIiwKICAgIHZhbHVlcyA9IHN0YXRlX3BhbGxldCwKICAgIGxhYmVscyA9IHN0YXRlX2ZpdCAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkKICApICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCgiIix2YWx1ZXMgPSAiZ3JleTkwIgogICkgKwogIGZhY2V0X2dyaWQoc3BwfnNwYXRpYWwpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDE5NzksMjAxNSw5KSxsaW1pdHMgPSBjKDE5NzksMjAxNSkpKwogIHhsYWIoIlllYXIiKSArCiAgbXlfZ2d0aGVtZV9wKGxlZ19wb3MgPSAicmlnaHQiLCBoanVzdCA9IDAuOSxheF90eF9zID0gMTQsbGVnX3R4X3MgPSAxNiwgbGVnX3RsX3MgPSAxOCxheF90bF9zID0gMTgsZmFjZXRfdHhfcyA9IDE2KSArCiAgdGhlbWUobGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMSwibGluZSIpLAogICAgICAgIGxlZ2VuZC50aXRsZS5hbGlnbj0wLjUpCgoKICBnZ3NhdmUoZmlsZW5hbWUgPSAiYXJlYV9wbG90X2F2Z19zcHBfc3B0bC5qcGciLAogICAgICAgICBwbG90ID0gc3NwX2FyZWEsCiAgICAgICAgIHBhdGggPSBteV9wYXRoKCJSIiwiRmlndXJlcyIpLAogICAgICAgICB3aWR0aCA9IDE0LAogICAgICAgICBoZWlnaHQgPSA4CiAgKQoKCmBgYAo8IS0tICFbUHJvcG9ydGlvbiBjaGFuZ2UgYWdncmVnYXRlZCBhbGwgc3BlY2llcyBtYXAgZm9yIHBhcGVyXSgvVm9sdW1lcy9FbnRlcnByaXNlL0RhdGEvQWNyb3NzQm91bmRhcmllcy9SZXN1bHRzL0ZpZ3VyZXMvYXJlYV9wbG90X2F2Z19zcHBfc3B0bC5qcGcpIC0tPgoKIyBPbGQgY29kZQoKIyMgRmlzaGluZyBwb3J0cyBXUEkKCldlIHVzZWQgW0dsb2JhbCBGaXNoaW5nIFdhdGNoXShodHRwczovL2dsb2JhbGZpc2hpbmd3YXRjaC5vcmcvZGF0YXNldHMtYW5kLWNvZGUtYW5jaG9yYWdlcy8pJ3MgZGF0YWJhc2Ugb24gCkFuY2hvcmFnZXMsIFBvcnRzIGFuZCBWb3lhZ2VzLgoKKlRoZSBHbG9iYWwgRmlzaGluZyBXYXRjaCBhbmNob3JhZ2VzIGRhdGFzZXQgaXMgYSBnbG9iYWwgZGF0YWJhc2Ugb2YgYW5jaG9yYWdlIGxvY2F0aW9ucyB3aGVyZSB2ZXNzZWxzIGNvbmdyZWdhdGUuIFRoZSBkYXRhc2V0IGNvbnRhaW5zIG92ZXIgMTYwLDAwMCBpbmRpdmlkdWFsIGFuY2hvcmFnZSBsb2NhdGlvbnMsIHdoaWNoIGFyZSBmdXJ0aGVyIGdyb3VwZWQgaW50byBuZWFybHkgMzIsMDAwIHBvcnRzIHdoZW4gYXBwbGljYWJsZS4qCgoKYGBge3IgcG9ydHNfc2YsIGV2YWwgPSBULCBlY2hvID0gVH0KCiMgR2V0IEdsb2JhbCBGaXNoaWcgV2F0Y2ggZGF0YQpnZndfZGF0YSA8LSBteV9wYXRoKCJEIiwiU3BhdGlhbCIsbmFtZSA9ICJnZndfcG9ydGRhdGEuY3N2IiwgcmVhZCA9IFQpICU+JSAKICBmaWx0ZXIoaXNvMyA9PSAiVVNBIikgCgojIFZpc3VhbGl6ZSBkYXRhIChvLmshKQojIGdncGxvdChnZndfZGF0YSkgKwojICAgZ2VvbV9wb2ludCgKIyAgICAgYWVzKAojICAgICB4ID0gbG9uLAojICAgICB5ID0gbGF0CiMgICApCiMgICApCgojIENvbnZlcnQgZGF0YSB0byBzZiBmb3IgbWVyZ2lnCmdmd19zZiA8LSBzdF9hc19zZihnZndfZGF0YSwKICAgICAgICAgICAgIGNvb3JkcyA9IGMoImxvbiIsICJsYXQiKSwKICAgICAgICAgICAgIGNycyA9IDQzMjYpCgojIE1lcmdlIGRhdGEgd2l0aCBzdGF0ZSB3YXRlcnMgdG8sbG9jYXRlIHBvcnRzIApwb3J0X3NmIDwtIHN0X2pvaW4oZ2Z3X3NmLHN0YXRlX3NmKSAlPiUgCiAgZmlsdGVyKCFpcy5uYShqdXJpc2RpY3RpKSkgIyByZW1vdmUgcG9pbnRzIG91dHNpZGUgc3RhdCB3YXRlcnMKCmdncGxvdChwb3J0X3NmKSAgKwogIGdlb21fc2YoYWVzKGNvbG9yID0gZGlzdGFuY2VfZnJvbV9zaG9yZV9tKSkgKwogIHRoZW1lX2RhcmsoKQoKYGBgClNvLi4uTG9va3MgbGlrZSBzb21lIHBvcnRzIGFyZSAiZmFyIGZyb20gc2hvcmUiIHdoaWNoIEkgZG9uJ3QgcmVhbGx5IGtub3cgd2hhdCBpdCBtZWFucy4gRm9yIG5vdywgSSBhbSBvbmx5IHNlbGVjdGluZyB0aG9zZSBwb3J0cyB0aGF0IGFyIDAgbWV0ZXIgZnJvbSBzaG9yZS4gCgoKYGBge3IgcG9ydHNfaW5zaG9yZSwgZXZhbCA9IFQsIGVjaG8gPSBGfQoKIyBHZXQgbnVtYmVyIG9mIHBvcnRzIHBlciBzdGF0ZQpwb3J0c19uX2RhdGEgPC0gcG9ydF9zZiAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICAgIGZpbHRlcihkaXN0YW5jZV9mcm9tX3Nob3JlX20gPT0gMCkgJT4lIAogICAgZ3JvdXBfYnkoc3RhdGUpICU+JSAKICAgIHN1bW1hcmlzZShuX3BvcnRzID0gbigpKSAKCiMgcGxvdCBpdApncmlkRXh0cmE6OmdyaWQuYXJyYW5nZSgKICBwb3J0X3NmICU+JSAKICAgIGZpbHRlcihkaXN0YW5jZV9mcm9tX3Nob3JlX20gPT0gMCkgJT4lIAogICAgZ2dwbG90KCkgICsKICAgIGdlb21fc2YoYWVzKGNvbG9yID0ganVyaXNkaWN0aSkpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQpICsKICAgIHRoZW1lX2RhcmsoKSArCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiIiksCiAgdGFibGVHcm9iKHBvcnRzX25fZGF0YSksCiAgbmNvbCA9IDIKKQoKCmBgYAoKClRoZXJlIGFyZSBzdGlsbCB0b28gbWFueSBwb3J0cyBpbiBlYWNoIHN0YXRlICg/KS4gU3BlY2lhbGx5IE5ldyBKZXJzZXkhIE9uZSBhcHByb2FjaCBpcyB0byB1c2UgTk9BQSdzIGxhbmRpbmctcGVyLXBvcnQgZGF0YSB0byBmaWx0ZXIgb3V0Li4uIAoKIyMjIyMjIDQuMiBXb3JsZCBQb3J0IEluZGV4IAoKSW4gdGhpcyBhcHByb2FjaCB3ZSBvbmx5IHVzZSB0aGUgcG9ydHMgY2F0ZWdvcml6ZWQgd2l0aGluIHRoZSBbV1BJXShodHRwczovL21zaS5uZ2EubWlsL05HQVBvcnRhbC9NU0kucG9ydGFsP19uZnBiPXRydWUmX3BhZ2VMYWJlbD1tc2lfcG9ydGFsX3BhZ2VfNjImcHViQ29kZT0wMDE1KSBhbmQgd2l0aCBgZGlzdGFuY2VfZnJvbV9zaG9yZV9tID09IDBgICBhbmQgYGF0X2RvY2sgPT0gVFJVRWAuCgotIGBhdF9kb2NrYCA9PSBBbmNob3JhZ2VzIHdpdGhpbiBhIDQ1MCBtZXRlciBidWZmZXIgYXJvdW5kIGEgY29tYmluZWQgbGFuZCBzaGFwZSBmaWxlIGFyZSBjb25zaWRlcmVkIGF0IGRvY2suIAoKYGBge3Igd3BpX2FwcHJvYWNoLCBldmFsID0gVCwgZWNobyA9IEZ9CgpncmlkRXh0cmE6OmdyaWQuYXJyYW5nZSgKICBwb3J0X3NmICU+JSAKICAgIGZpbHRlcihkaXN0YW5jZV9mcm9tX3Nob3JlX20gPT0gMCwKICAgICAgICAgICBsYWJlbF9zb3VyY2UgJWluJSBjKCJXUElfcG9ydHMiKSwKICAgICAgICAgICBhdF9kb2NrID09IFRSVUUpICU+JSAKICAgIGdncGxvdCgpICArCiAgICBnZW9tX3NmKGFlcyhjb2xvciA9IGp1cmlzZGljdGkpKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gc3RhdGVfcGFsbGV0KSArCiAgICB0aGVtZV9kYXJrKCksCiAgcG9ydF9zZiAlPiUgCiAgICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogICAgZmlsdGVyKGRpc3RhbmNlX2Zyb21fc2hvcmVfbSA9PSAwLAogICAgICAgICAgIGxhYmVsX3NvdXJjZSAlaW4lIGMoIldQSV9wb3J0cyIpLAogICAgICAgICAgIGF0X2RvY2sgPT0gVFJVRSkgJT4lIAogICAgZ3JvdXBfYnkoc3RhdGUpICU+JSAKICAgIHN1bW1hcmlzZShuX3BvcnRzID0gbigpKSAlPiUgCiAgICB0YWJsZUdyb2IoKSwKICBuY29sID0gMgopCgoKYGBgCgojIyBIaXN0b3JpYyBxdW90YSBWcyBkaXN0cmlidXRpb25zCgpUaGlzIHNlY3Rpb24gb2YgdGhlIHJlc3VsdHMgZXhwbG9yZXMgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIGhpc3RvcmljIGRpc3RyaWJ1dGlvbiBvZiB0ZSBzdG9jayBhbmQgdGhlIGhpc3RvcmljIHF1b3RhIGFsbG9jYXRpb24uIFdlIGNvbGxlY3RlZCB0aGUgcHJvcG9ydGlvbiBvZiB0aGUgdG90YWwgcXVvdGEgdGhhdCBlYWNoIFN0YXRlIGdldHMgZm9yIGVhY2ggc3BlY2llcy4KClJpZ2h0IG5vdyB0aGUgYW5hbHlzaXMgb25seSBjb3ZlcnMgYmxhY2sgc2VhIGJhc3MsIHN1bW1lciBmbG91bmRlciBhbmQgc2N1cC4gQnV0IHdlIGNhbiBnbyBzcGVjZWlzIGJ5IHNwZWNpZXMgdG8gc2VlIHdoaWNoIG9uZXMgaGF2ZSB0aGVpciBxdW90YSBhbGxvY2F0ZWQgYnkgc3RhdGUgdG8gaW5jbHVkZSB0aGVtIGluIHRoZSBhbmFseXNpcy4KCi0gW0JsYWNrIFNlYSBCYXNzOyAqQ2VudHJvcHJpc3RpcyBzdHJpYXRhKl0oaHR0cHM6Ly93d3cubWFmbWMub3JnL25ld3NmZWVkLzIwMjEvYXNtZmMtYW5kLW1hZm1jLWFwcHJvdmUtYnNiLWNvbW1lcmNpYWwtYWxsb2NhdGlvbi1jaGFuZ2VzKQoKKipOb3RlOioqIFdlIGFyZSB1c2luZyB0aGUgbmV3IGFsbG9jYXRpb25zIGJhc2VkIG9uIHRoZSBzdG9jaydzIG1vc3QgcmVjZW50IGJpb21hc3MgZGlzdHJpYnV0aW9uKiAKCi0gW1N1bW1lciBmbG91bmRlcl0oaHR0cDovL3d3dy5hc21mYy5vcmcvdXBsb2Fkcy9maWxlLzVmOWFmODJhMjAxOVN1bW1lckZsb3VuZGVyRk1QX1Jldmlldy5wZGYpCgotIFtTY3VwXShodHRwOi8vd3d3LmFzbWZjLm9yZy91cGxvYWRzL2ZpbGUvNWY5OWQwMTEyMDE5X1NjdXBfRk1QX1Jldmlld19hcHByb3ZlZC5wZGYpIFN1bW1lciBwZXJpb2QKCkZvciBTdGF0ZS1sZXZlbCBtYW5hZ2VkIHNwZWNpZXMgc2VlIHRoZSBbQXRsYW50aWMgU3RhdGVzIE1hcmluZSBGaXNoZXJpZXMgQ29taXNzaW9uXShodHRwOi8vd3d3LmFzbWZjLm9yZy9maXNoZXJpZXMtbWFuYWdlbWVudC9wcm9ncmFtLW92ZXJ2aWV3KSB3ZWJzaXRlIGFuZCBnbyBzcGVjaWVzLWJ5LXNwZWNpZXMuCgoKYGBge3Igc3RhdGVfcXVvdGFfdGJsLGV2YWw9IFQsIGVjaG8gPSBUfQoKcXVvdGFfYWxsb2NhdGlvbiA8LSBzdGF0ZV9sYXQgJT4lIAogIG11dGF0ZSgKICAgICJDZW50cm9wcmlzdGlzIHN0cmlhdGEiID0gYygKICAgICAgMC4wMDQwLCAjTUUKICAgICAgMC4wMDQwLCAjTkgKICAgICAgMC4xNTY0LCAjTUEKICAgICAgMC4xMzIzLCAjUkkKICAgICAgMC4wMzY3LCAjQ1QKICAgICAgMC4wODU3LCAjTlkKICAgICAgMC4yMDEwLCAjTkoKICAgICAgMC4wNDExLCAjREUKICAgICAgMC4wODg4LCAjTUQKICAgICAgMC4xNjE0LCAjVkEKICAgICAgMC4wODg4ICNOQwogICAgKSwKICAgICJQYXJhbGljaHRoeXMgZGVudGF0dXMiID0gYygKICAgICAgMC4wMDA0NzU2LCAjTUUgCiAgICAgIDAuMDAwMDA0NiwgI05IIAogICAgICAwLjA2ODIwNDYsICNNQSAKICAgICAgMC4xNTY4Mjk4LCAjUkkgCiAgICAgIDAuMDIyNTcwOCwgI0NUIAogICAgICAwLjA3NjQ2OTksICNOWSAKICAgICAgMC4xNjcyNDk5LCAjTkogCiAgICAgIDAuMDAwMTc3OSwgI0RFIAogICAgICAwLjAyMDM5MTAsICNNRAogICAgICAwLjIxMzE2NzYsICNWQQogICAgICAwLjI3NDQ1ODQgI05DCiAgICApLAogICAgIlN0ZW5vdG9tdXMgY2hyeXNvcHMiID0gYygKICAgICAgMC4wMDEyMTAxLCAjTUUKICAgICAgMC4wMDAwMDAwLCAjSE4KICAgICAgMC4yMTU4NzI5LCAjTUEKICAgICAgMC41NjE5NDU2LCAjUkkKICAgICAgMC4wMzE1Mzk5LCAjQ1QKICAgICAgMC4xNTgyNDY2LCAjTlkKICAgICAgMC4wMjkxNjY3LCAjTkoKICAgICAgMC4wMDAwMDAwLCAjREUKICAgICAgMC4wMDAxMTkwLCAjTUQKICAgICAgMC4wMDE2NTAyLCAjVkEKICAgICAgMC4wMDAyNDkwICNOQwogICAgKQogICkgJT4lIAogIGdhdGhlcigic3BwIiwicXVvdGEiLDQ6NikKCiMgRG91YmxlIGNoZWNrIHRoZXkgYWxsIGFkZCB0byAxLi4uCnF1b3RhX2FsbG9jYXRpb24gJT4lIAogIGdyb3VwX2J5KHNwcCkgJT4lIAogIHN1bW1hcmlzZV9hdCh2YXJzKHF1b3RhKSxzdW0pCgoKcXVvdGFfYWxsb2NhdGlvbiAlPiUgCiAgYXJyYW5nZShvcmRlcikgJT4lIAogIHNlbGVjdCgtb3JkZXIpICU+JSAKICBzcHJlYWQoc3BwLHF1b3RhKSAlPiUgCiAga2FibGUoKQpgYGAKCgojIyMgR2V0IGRhdGEgcmVhZHkKCmBgYHtyfQoKdG90YWxfZml0ZWQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieSh5ZWFyLHJlZ2lvbixzcHApICU+JSAKICBzdW1tYXJpc2UodG90YWxfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09VCksLmdyb3VwcyA9ICJkcm9wIikKCiMgZ3JvdXAgYnkgc3RhdGUKc3RhdGVfZml0IDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixyZWdpb24sc3BwKSAlPiUgCiAgc3VtbWFyaXNlKHN0YXRlX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGxlZnRfam9pbih0b3RhbF9maXRlZCwKICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwicmVnaW9uIiwic3BwIikpICU+JQogIG11dGF0ZShwZXJjZW50YWdlID0gc3RhdGVfdmFsdWUvdG90YWxfdmFsdWUqMTAwKSAlPiUgCiAgI09ubHkgc2hvdyByZXN1bHRzIGZvciBzcHJpbmcKICBmaWx0ZXIoc3RyX2RldGVjdChyZWdpb24sIlNwcmluZyIpKQoKcXVvdGFfZGYgPC0gcXVvdGFfYWxsb2NhdGlvbiAlPiUgCiAgbGVmdF9qb2luKGhpc3RvcmljX3NwcCkgJT4lIAogIGdyb3VwX2J5KHN0YXRlLGFicmV2LHllYXIscmVnaW9uLHNwcCxxdW90YSkgJT4lIAogIHN1bW1hcmlzZShzdGF0ZV92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT0gVCksIC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICBsZWZ0X2pvaW4odG90YWxfZml0ZWQsCiAgICAgICAgICAgIGJ5ID0gYygieWVhciIsInJlZ2lvbiIsInNwcCIpKSAlPiUKICBtdXRhdGUoRGlzdHJpYnV0aW9uID0gc3RhdGVfdmFsdWUvdG90YWxfdmFsdWUqMTAwLAogICAgICAgICBIaXN0b3JpYyA9IHF1b3RhKjEwMCkgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHF1b3RhLHNwcCkgJT4lIAogIG11dGF0ZShSTWVhbiA9IHpvbzo6cm9sbG1lYW4oeCA9IERpc3RyaWJ1dGlvbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGwgPSBOQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hLnJtPVQpCiAgICApICU+JSAKICAjT25seSBzaG93IHJlc3VsdHMgZm9yIHNwcmluZwogIGZpbHRlcihzdHJfZGV0ZWN0KHJlZ2lvbiwiU3ByaW5nIiksCiAgICAgICAgICFpcy5uYShSTWVhbikgIyBSZW1vdmUgTkFzIGZyb20gcm9sbG1lYW4KICAgICAgICAgKSAlPiUgIAogIGxlZnRfam9pbihzdGF0ZV9sYXQpICU+JSAKICBmaWx0ZXIoCiAgICAjIHNwcCA9PSJDZW50cm9wcmlzdGlzIHN0cmlhdGEiCiAgICBzcHAgJWluJSBxdW90YV9hbGxvY2F0aW9uJHNwcAogICkKCmhlYWQocXVvdGFfZGYpICU+JSAKICBrYWJsZSgpCmBgYAoKIyMjIEV4cGxvcmluZyBkaWZmZXJlbnQgd2F5cyB0byBzaG93IHRoZSByZXN1bHRzCgojIyMjIERpZmZlcmVuY2UgbGluZSBwbG90CgpUaGlzIHZlcnNpb24gc2hvd3MgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgSGlzdG9yaWMgcXVvdGEgYWxsb2NhdGlvbiBhbmQgdGhlIGRpc3RyaWJ1dGlvbiBwcm9wb3J0aW9uIG9mIHRoZSBzdG9jazoKCi0gZGlmZiA8IDAgPSB0aGUgZGlzdHJpYnV0aW9uIHByb3BvcnRpb24gaXMgKmxhcmdlciogdGhhbiB0aGUgYWxsb2NhdGVkIHF1b3RhCi0gZGlmZiA+IDAgPSB0aGUgZGlzdHJpYnV0aW9uIHByb3BvcnRpb24gaXMgKnNtYWxsZXIqIHRoYW4gdGhlIGFsbG9jYXRlZCBxdW90YSAKCmBgYHtyfQojIE9wdGlvbiBvbmUKCnF1b3RhX2RmICU+JQogIG11dGF0ZShkaWZmID0gSGlzdG9yaWMtIERpc3RyaWJ1dGlvbiwKICAgICAgICAgZGlmZl9ybWVhbiA9IFJNZWFuLSBEaXN0cmlidXRpb24pICU+JSAKICBnYXRoZXIoInR5cGUiLCJ2YWx1ZSIsZGlmZjpkaWZmX3JtZWFuKSAlPiUgCiAgIyBWaWV3KCkKICBnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKAogICAgYWVzKAogICAgICB4ID0geWVhciwKICAgICAgeSA9IHZhbHVlLAogICAgICBjb2xvciA9IG9yZGVyCiAgICApCiAgKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKCJTdGF0ZSIsCiAgICB2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQsCiAgICBsYWJlbHMgPSBxdW90YV9kZiAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkKICAgICkgKwogIGZhY2V0X2dyaWQodHlwZX5zcHAsIAogICAgICAgICAgICAgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfZGFyaygpCgpgYGAKIyMjIyBMaW5ldHlwZSBwbG90CgpIZXJlLCB3ZSBwbG90IHRoZSBkaXN0cmlidXRpb25hbCBxdW90YSAoc29saWQgbGluZXMpIHdpdGggZWFjaCBTdGF0ZSdzIGFsbG9jYXRpb24gd2l0aCBkYXNoZWQgKC0tLS0pIGxpbmVzCgpgYGB7cn0KIyBPcHRpb24gb25lCgpxdW90YV9kZiAlPiUgCiAgZ2F0aGVyKCJsZXZlbCIsInF1b3RhIixEaXN0cmlidXRpb246Uk1lYW4pICU+JSAKICAjIG11dGF0ZShkaWZmID0gcXVvdGFfcGVyLSBwZXJjZW50YWdlKSAlPiUgCiAgIyBWaWV3KCkKICBnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKAogICAgYWVzKAogICAgICB4ID0geWVhciwKICAgICAgeSA9IHF1b3RhLAogICAgICBjb2xvciA9IG9yZGVyCiAgICApCiAgKSArCiAgbGFicyh4ID0gIlllYXIiLHkgPSAiUXVvdGEgKCUpIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKCJTdGF0ZSIsCiAgICB2YWx1ZXMgPSBzdGF0ZV9wYWxsZXQsCiAgICBsYWJlbHMgPSBxdW90YV9kZiAlPiUgYXJyYW5nZShvcmRlcikgJT4lICBwdWxsKHN0YXRlKSAlPiUgdW5pcXVlKCkKICAgICkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgiU3RhdGUiLAogICAgdmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgbGFiZWxzID0gcXVvdGFfZGYgJT4lIGFycmFuZ2Uob3JkZXIpICU+JSAgcHVsbChzdGF0ZSkgJT4lIHVuaXF1ZSgpCiAgICApICsKICBzY2FsZV9saW5ldHlwZSgiUXVvdGEiKSArCiAgZmFjZXRfZ3JpZChzcHAgfiBsZXZlbCkrCiAgdGhlbWVfZGFyaygpCgpgYGAKIyMjIyBFZmZpY2llbmN5IGluZGV4CgpUaGUgaWRlYSBoZXJlIGlzIGNyZWF0ZSBhbmQgKmVmZmljaWVuY3kgaW5kZXgqIChEYW5nZXIhKSB0aGF0IGNvbXB1dGVzIHRoZSBhbGlnbm1lbnQgYmV0d2VlbiB0aGUgZGlzdHJpYnV0aW9uIGFuZCB0aGUgYWN0dWFsIGFsbG9jYXRpb24uIFRoZSBpbmRleCBpcyBzaW1wbHk7CgokJGVpID0gXGZyYWN7SGlzdG9yaWNRdW90YX17RGlzdHJpYnV0aW9uUHJvcG9ydGlvbn0kJCAKU28sIGluIGNhc2VzIHdoZXJlICplaSogPSAxLCB0aGUgcXVvdGEgaXMgYWxpZ25lZCB3aXRoIHRoZSBkaXN0cmlidXRpb247IHdoZW4gKmVpKiA+IDEgdGhlbiB0aGUgaGlzdG9yaWMgcXVvdGEgaXMgbW9yZSB0aGFuIHRoZSBzdG9jaydzIFN0YXRlJ3MgZGlzdHJpYnV0aW9uLCBjb250cmFyaWx5LCAqZWkqIDwgMSBtZWFucyB0aGF0IHRoZSBoaXN0b3JpYyBxdW90YSBpcyBsZXNzIHRoYW4gd2hhdCB0aGUgU3RhdGUgY3VycmVudGx5IGhhcy4KCgoqKk5vdGU6KiogCi0gVGhlcmUgYXJlIHNvbWUgY3Jhenp5IG91dGxpZXJzIHRoYXQgaGF2ZSBiZWVuIHJlbW92ZWQsIGZvciBub3cuLi4gCi0gQm90dG9tIHBsb3QgcmVwcmVzZW50aW5nIGluZGV4IGFzIGEgUm1lYW4KCiMjIyMjIEFzIGEgbm9ybWFsIHllYXIgdG8geWVhcgoKYGBge3J9CiMgT3B0aW9uIG9uZQoKZWZmX2luZGV4IDwtIHF1b3RhX2RmICU+JSAKICAjIGZpbHRlcigKICAjICAgc3BwID09IkNlbnRyb3ByaXN0aXMgc3RyaWF0YSIKICAjICkgJT4lIAogIG11dGF0ZShpbmRleCA9IERpc3RyaWJ1dGlvbi9IaXN0b3JpYywKICAgICAgICAgaW5kZXhfcm1lYW4gPSBSTWVhbi9IaXN0b3JpYykgJT4lCiAgZ2F0aGVyKCJsZXZlbCIsImluZGV4IixpbmRleDppbmRleF9ybWVhbikgJT4lCiAgZmlsdGVyKGluZGV4IDwgNSkgIyB0aGVyZSBhcmUgc29tZSBjcmFhYWF6eSBvdXRsaWVycwogICMgVmlldygpCiAgCmdncGxvdChlZmZfaW5kZXgpICsKICBnZW9tX2xpbmUoCiAgICBhZXMoCiAgICAgIHggPSB5ZWFyLAogICAgICB5ID0gaW5kZXgsCiAgICAgIGNvbG9yID0gc3RhdGUKICAgICksCiAgKSArCiAgbGFicyh4ID0gIlllYXIiLHkgPSAiRWZmaWNpZW5jeSBpbmRleCIpICsKICBzY2FsZV9maWxsX21hbnVhbCgiU3RhdGUiLAogICAgdmFsdWVzID0gc3RhdGVfcGFsbGV0LAogICAgbGFiZWxzID0gcXVvdGFfZGYgJT4lIGFycmFuZ2Uob3JkZXIpICU+JSAgcHVsbChzdGF0ZSkgJT4lIHVuaXF1ZSgpCiAgICApICsKICBzY2FsZV9jb2xvcl9tYW51YWwoIlN0YXRlIiwKICAgIHZhbHVlcyA9IHN0YXRlX3BhbGxldCwKICAgIGxhYmVscyA9IHF1b3RhX2RmICU+JSBhcnJhbmdlKG9yZGVyKSAlPiUgIHB1bGwoc3RhdGUpICU+JSB1bmlxdWUoKQogICAgKSArCiAgZmFjZXRfZ3JpZChsZXZlbH5zcHAsCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZSIpKwogIHRoZW1lX2RhcmsoKQoKYGBgCgojIyBOT0FBcyBwb3J0IGFwcHJvYWNoCgpgYGB7ciBub2FhX2xhbmRpbmdzLCBldmFsID0gRiwgZWNobyA9IEZ9Cgpub2FhX2xhbmRpbmdzIDwtIHJlYWQuY3N2KCIvVm9sdW1lcy9FbnRlcnByaXNlL0RhdGEvQWNyb3NzQm91bmRhcmllcy9EYXRhL05PQUEvbGFuZGluZ3NfYnlfdG9wX3VzX3BvcnRzLmNzdiIpCgoKbm9hYV9sYW5kaW5ncyAlPiUgCiAgY2xlYW5fbmFtZXMoKSAlPiUgCiAgVmlldygpCgpzdGF0ZV90b3RhbHMgPC0gYXMuZGF0YS5mcmFtZShzdHJfc3BsaXRfZml4ZWQobm9hYV9sYW5kaW5ncyRQb3J0LiwgIiwiLDIpKSAlPiUgCiAgcmVuYW1lKG5hbWUgPSBWMSwKICAgICAgICAgYWJydiA9IFYyKSAlPiUgCiAgYmluZF9jb2xzKG5vYWFfbGFuZGluZ3MpICU+JSAKICBtdXRhdGUoYWJydiA9IHN0cl9zcXVpc2goYWJydikpICU+JSAKICBjbGVhbl9uYW1lcygpICU+JSAKICBmaWx0ZXIoYWJydiAlaW4lICBjKCJDVCIsIkRFIiwiTUUiLCJNRCIsIk1BIiwiTkgiLCJOSiIsIk5ZIiwiTkMiLCJSSSIsIlZBIikpICU+JSAKICBmaWx0ZXIoeWVhciA+PSAyMDEwKSAlPiUgCiAgZ3JvdXBfYnkoYWJydikgJT4lIAogIHN1bW1hcmlzZSh0b3RhbF9wb3VuZHNfbWlsbGlvbiA9IHN1bShtaWxsaW9uc19vZl9wb3VuZHMpLAogICAgICAgICAgICB0b3RhbF9kbHJfbWlsbGlvbiA9IHN1bSh4X21pbGxpb25zX29mX2RvbGxhcnMpCiAgKQoKIyBFc3RpbWF0ZSBwZXJjZW50YWdlcwpwb3J0X2RhdGEgPC0gYXMuZGF0YS5mcmFtZShzdHJfc3BsaXRfZml4ZWQobm9hYV9sYW5kaW5ncyRQb3J0LiwgIiwiLDIpKSAlPiUgCiAgcmVuYW1lKG5hbWUgPSBWMSwKICAgICAgICAgYWJydiA9IFYyKSAlPiUgCiAgYmluZF9jb2xzKG5vYWFfbGFuZGluZ3MpICU+JSAKICBtdXRhdGUoYWJydiA9IHN0cl9zcXVpc2goYWJydikpICU+JSAKICBjbGVhbl9uYW1lcygpICU+JSAKICBmaWx0ZXIoYWJydiAlaW4lICBjKCJDVCIsIkRFIiwiTUUiLCJNRCIsIk1BIiwiTkgiLCJOSiIsIk5ZIiwiTkMiLCJSSSIsIlZBIikpICU+JSAKICBmaWx0ZXIoeWVhciA+PSAyMDEwKSAlPiUgCiAgZ3JvdXBfYnkoYWJydixuYW1lLHBvcnQpICU+JSAKICBzdW1tYXJpc2Uoc3VtX3BvdW5kc19taWxsaW9uID0gc3VtKG1pbGxpb25zX29mX3BvdW5kcyksCiAgICAgICAgICAgIHN1bV9kbHJfbWlsbGlvbiA9IHN1bSh4X21pbGxpb25zX29mX2RvbGxhcnMpCiAgICAgICAgICAgICkgJT4lIAogIGxlZnRfam9pbihzdGF0ZV90b3RhbHMpICU+JSAKICBtdXRhdGUoCiAgICBwZXJfc3VtID0gc3VtX2Rscl9taWxsaW9uL3RvdGFsX2Rscl9taWxsaW9uKjEwMCwKICAgIHBlcl9wbmRzID0gc3VtX3BvdW5kc19taWxsaW9uL3RvdGFsX3BvdW5kc19taWxsaW9uKjEwMCwKICAgIGN1bV9wZXJfc3VtID0gY3Vtc3VtKHN1bV9kbHJfbWlsbGlvbi90b3RhbF9kbHJfbWlsbGlvbioxMDApLAogICAgY3VtX3Blcl9wbmRzID0gY3Vtc3VtKHN1bV9wb3VuZHNfbWlsbGlvbi90b3RhbF9wb3VuZHNfbWlsbGlvbioxMDApCiAgKQoKIAoKCiAgIyBGdW5jdGlvbiB0byBnZXQgcGVyY2VudGlsZXMKICAgICAgIyBodHRwczovL3d3dy50aWR5dmVyc2Uub3JnL2Jsb2cvMjAyMC8wMy9kcGx5ci0xLTAtMC1zdW1tYXJpc2UvCiAgICAgIHF1aWJibGUgPC0gZnVuY3Rpb24oeCwgcSA9IHApIHsKICAgICAgICB0aWJibGUoeCA9IHF1YW50aWxlKHgsIHEpLCBxID0gcSkKICAgICAgfQogICAgICAjIEdldCB0aGUgcGVyY2VudGlsZSB0cmVzaG9sZCBwZXIgeWVhciwgZW5zZW1ibGUgYW5kIG5laWdoYm91ciBpZAogICAgcGVyY2VudGlsZSA8LSBwb3J0X2RhdGEgJT4lIAogICAgICAgIGdyb3VwX2J5KGFicnYpICU+JQogICAgICAgIGRvKHF1aWJibGUoLiRjb21fc3VtLCAwLjUwKSkgJT4lIAogICAgICBsZWZ0X2pvaW4ocG9ydF9kYXRhKSAlPiUgCiAgICAgIG11dGF0ZShkcm9wID0gaWZlbHNlKHggPCBzdW1fZGxyX21pbGxpb24sImRyb3AiLCJrZWVwIiApKSAlPiUgCiAgICAgIGZpbHRlcihkcm9wID09ICJrZWVwIikKCiAKIAojIE51bWJlciBvZiBwb3J0cyBwZXIgc3RhdGUKcGVyY2VudGlsZSAlPiUKICBncm91cF9ieShhYnJ2KSAlPiUKICBzdW1tYXJpc2UobigpKSAlPiUgCiAgbGVmdF9qb2luKG9yaWdpbmFsX24pICU+JSBWaWV3KCkKCgp1bmlxdWUocG9ydF9kYXRhJGFicnYpCmxlbmd0aCh1bmlxdWUocG9ydF9kYXRhJGFicnYpKQoKIyBHZXQgcmFuayBieSBkb2xhcgp0b3BfZGxyIDwtIHBvcnRfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoYWJydikgJT4lCiAgIyBWaWV3KCkKICB0b3BfbigxMCxzdW1fZGxyX21pbGxpb24pCgojIEdldCByYW5rIGJ5IGxhbmRpbmcKdG9wX3BuZCA8LSBwb3J0X2RhdGEgJT4lIAogIGdyb3VwX2J5KGFicnYpICU+JQogICMgVmlldygpCiAgdG9wX24oMTAsc3VtX3BvdW5kc19taWxsaW9uKQoKIyBCaW5kIHBvcnRzIGFuZCBtYW51YWxseSBzZXQgY29ycmRpbmF0ZXMKdG9wX3BvcnRzIDwtIHRvcF9kbHIgJT4lIAogIGZ1bGxfam9pbih0b3BfcG5kKSAlPiUgCiAgYXJyYW5nZShhYnJ2KSAlPiUgCiAgZ3JvdXBfYnkoYWJydikgJT4lIAogIHN1bW1hcmlzZShuKCkpCiAgCiAgCiAgCiAgCiAgIyBNYW51YWxseSBlc3RpbWF0ZWQgZnJvbSBnb29nbGUgbWFwcwogIGJpbmRfY29scygKICAgIGxhdCA9IGMoNDEuMzM0NTQ3NjgxNjc0NCwKICAgICAgICAgICAgNDEuMzQxMzgzODg2MDA1NjksCiAgICAgICAgICAgIDQxLjYzNjQ2NzA2NTYyNjUwNSwKICAgICAgICAgICAgMzguMzIzNDc3ODc3MjAyNjIsIAogICAgICAgICAgICA0NC4xNTM4NjU0MTUxOTIwMiwgCiAgICAgICAgICAgIDQzLjY2NjE3MzU3ODc2MjkzLAogICAgICAgICAgICAzNS45MDQwMDk4NDUwODA1NCwgCiAgICAgICAgICAgIDQzLjExMjM4MzgzMTI4ODksCiAgICAgICAgICAgIDM4Ljk3MTM5NDAxODc1MDI5NiwgCiAgICAgICAgICAgIDQxLjA1MjY4MzE4MTc5MDA5LCAKICAgICAgICAgICAgNDEuMzcwNTQ4MDA4MjM4OTYsIAogICAgICAgICAgICAzNi45OTI4NTg2MDEzMjk4MzYsIAogICAgICAgICAgICAzNy44Mzk2MzcxMzcyNDkyMzQKICAgICAgICAgICAgKSwKICAgIGxvbmcgPSBjKC03MS45MTMzMjc0NDAyODE5NiwKICAgICAgICAgICAgIC03Mi4wODIwMjU1NjU0NTg1OCwKICAgICAgICAgICAgIC03MC45MTk2NDQ0NjI2NTIxNiwKICAgICAgICAgICAgIC03NS4xMDE0MTgzNDg0MTYzLAogICAgICAgICAgICAgLTY4LjY2NDAyMTk2Nzc1OTgxLAogICAgICAgICAgICAgLTcwLjIyODgzODAxOTY5ODEsCiAgICAgICAgICAgICAtNzUuNTU1NTQwNTk2MTM3MTgsCiAgICAgICAgICAgICAtNzAuODU4MTU4NjY0OTU0ODQsCiAgICAgICAgICAgICAtNzQuODEyMjQxMzgyNjUwNywKICAgICAgICAgICAgIC03MS45Njg4MjU0NjI4OTM2LAogICAgICAgICAgICAgLTcxLjQ4MDMyNDUyNzI2MDgzLAogICAgICAgICAgICAgLTc2LjI2ODE3MTQ2NzMwMzk5LAogICAgICAgICAgICAgIC03Ni4yNDI5Mjc3MTkxNDk1NQogICAgICAgICAgICAgKQogICkgJT4lIAogICMgRGVsYXdhcmUKICBiaW5kX3Jvd3MoCiAgICBkYXRhLmZyYW1lKGFicnYgPSAiREUiLAogICAgICBuYW1lID0gIkluZGlhbiByaXZlciIsCiAgICAgIHBvcnQgPSAiSW5kaWFuIHJpdmVyLCBERSIsCiAgICAgIGxhdCA9IGFzLmRvdWJsZSgzOC42MjExMzU5MzQwMzc0NiksCiAgICAgIGxvbmcgPSAtNzUuMDYzOTcwMjE3MTgzNDUKICAgICAgKQogICkKCiMgd3JpdGVfY3N2KHRvcF9wb3J0cywidG9wX25ldXNfcG9ydHMuY3N2IikKCgogIHBvcnRfZGF0YSAlPiUgCiAgICBmaWx0ZXIoY29tX21lYW4gPj0gNzUpICU+JSAKICAgIGdyb3VwX2J5KGFicnYpICU+JSAKICAgIFZpZXcoKQogICAgc3VtbWFyaXNlKG4oKSkKCmBgYAoKCmBgYHtyIHJlbW92ZV9wZW4sIGV2YWwgPSBGLCBlY2hvID0gRn0KCiMjIyNfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyMjIyAKIyBTb2x2aW5nIGZvciBJc3N1ZSAjOCBQZW5uc3lsdmFuaWEgaGFzIE5PIGNvYXN0CiMjIyNfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyMjIyAKCiMgUmVtb3ZlIFBlbm5zeWx2YW5pYSBmcm9tIHNmCmdyaWRfZWV6X3NmIDwtICBzdF9yZWFkKCIvVm9sdW1lcy9FbnRlcnByaXNlL0RhdGEvQWNyb3NzQm91bmRhcmllcy9EYXRhL1NwYXRpYWwvZ3JpZF9zZi9ncmlkX2Vlel9zZi5zaHAiKSAlPiUKICBmaWx0ZXIoc3RhdGUgIT0gInBlbm5zeWx2YW5pYSIpCgojIE1ha2Ugc3VyZSBubyBQZW5uLgp1bmlxdWUoZ3JpZF9lZXpfc2Ykc3RhdGUpCgojIG92ZXIgd3JpdGUgc2YKd3JpdGVfc2YoZ3JpZF9lZXpfc2YsIHBhc3RlMChteV9wYXRoKCJEIiwgIlNwYXRpYWwiKSwiZ3JpZF9lZXpfc2Yuc2hwIikpCgojTWFrZSBzdXJlIG9mIHRoaW5ncwoKIyBncmlkX2Vlel9zZiA8LSAgc3RfcmVhZCgiL1ZvbHVtZXMvRW50ZXJwcmlzZS9EYXRhL0Fjcm9zc0JvdW5kYXJpZXMvRGF0YS9TcGF0aWFsL2dyaWRfc2YvZ3JpZF9lZXpfc2Yuc2hwIikKCiMgdW5pcXVlKGdyaWRfZWV6X3NmJHN0YXRlKQoKIyBOb3cgc2F2ZSBpdCBhcyBhIERGIHRvbwoKIyBncmlkX2Vlel9kZiA8LSBhcy5kYXRhLmZyYW1lKGdyaWRfZWV6X3NmKSAlPiUKICAjIHNlbGVjdChzdGF0ZSxpbmRleCkgJT4lCiAgIyBsZWZ0X2pvaW4obmVfZ3JpZCwKICAgICAgICAgICAgIyBieSA9ICJpbmRleCIpCgojIHdyaXRlX2NzdihncmlkX2Vlel9kZiwgcGFzdGUwKG15X3BhdGgoIlIiLCAiUGFydGlhbCIpLCJncmlkX2Vlel9kZi5jc3YiKSkKYGBgCgojIyMgRHluYW1pYyBmaWd1cmU6IEFnZ3JlZ2F0ZWQgUHJvcG9ydGlvbmFsIGNoYW5nZSBwZXIgc3VydmV5CgpgYGB7ciBhcmVhX21hcF9hZ2dyZWdhdGVkLCBldmFsID0gVCwgZWNobyA9IFQsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0PTZ9Cgp0b3RhbF9maXRlZCA8LSBoaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHllYXIscmVnaW9uLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2UodG90YWxfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09VCksLmdyb3VwcyA9ICJkcm9wIikKCgpzdGF0ZV9maXQgPC0gaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieShzdGF0ZSx5ZWFyLHJlZ2lvbixzcGF0aWFsKSAlPiUgCiAgc3VtbWFyaXNlKHN0YXRlX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGxlZnRfam9pbih0b3RhbF9maXRlZCwKICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwicmVnaW9uIiwic3BhdGlhbCIpKSAlPiUKICBtdXRhdGUocGVyY2VudGFnZSA9IHN0YXRlX3ZhbHVlL3RvdGFsX3ZhbHVlKjEwMCkgJT4lIAogIGxlZnRfam9pbihwZXJpb2RzLAogICAgICAgICAgICBieSA9ICJ5ZWFyIikgJT4lIAogIGdyb3VwX2J5KHN0YXRlLG9yZGVyLGxhYmVsLHJlZ2lvbixzcGF0aWFsKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcGVyID0gcm91bmQobWVhbihwZXJjZW50YWdlKSksLmdyb3VwcyA9ICJkcm9wIikKCiMgY2hlY2sgcGVyY2VudGFnZXMKIyBzdGF0ZV9maXQgJT4lIAojICAgZ3JvdXBfYnkocGVyaW9kKSAlPiUgCiMgICBzdW1tYXJpc2Uoc3VtKG1lYW5fcGVyKSkKCgpwIDwtIGxhbmRfc2YgJT4lIAogIGxlZnRfam9pbihzdGF0ZV9maXQsCiAgICAgICAgICAgIGJ5ID0gInN0YXRlIikgJT4lIAogIGdncGxvdCgpICsKICAjIGdlb21fc2YoYWVzKGZpbGwgPSBtZWFuX3BlcikpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gbWVhbl9wZXIsIHRleHQgPSBwYXN0ZShzdGF0ZSwgbWVhbl9wZXIsIiUgb2YgcHJvcG9ydGlvbiIpKSkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcygiQXZlcmFnZSBwcm9wb3J0aW9uIHBlciBTdGF0ZSIsIGFscGhhID0gMC44KSArCiAgZmFjZXRfd3JhcCh+IHJlZ2lvbiArIGxhYmVsICtzcGF0aWFsLCAKICAgICAgICAgICAgIG5yb3cgPSAyKSArCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIkxvbmdpdHVkZSIpICsKICBteV9nZ3RoZW1lX3AoZmFjZXRfdHhfcyA9IDEyLAogICAgICAgICAgICAgICBsZWdfcG9zID0gImJvdHRvbSIpICsKICB0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCgxLCJsaW5lIikpICsKICB0aGVtZV9kYXJrKCkKCmdncGxvdGx5KHAsCiAgICAgICAgIHRvb2x0aXAgPSAidGV4dCIsCiAgICAgICAgIGR5bmFtaWNUaWNrcyA9IEZBTFNFKSAlPiUgCiAgICBzdHlsZShob3ZlcmxhYmVsID0gbGlzdChiZ2NvbG9yID0gIndoaXRlIiksIGhvdmVyb24gPSAiZmlsbCIpCgoKYGBgCgoKYGBge3IgZXZhbCA9IEYsIGVjaG8gPSBULCByZXN1bHRzPSdoaWRlJ30KCnRvdGFsX2ZpdGVkIDwtIGhpc3RvcmljX3NwcCAlPiUKICBncm91cF9ieSh5ZWFyLHJlZ2lvbixzcHAsc3BhdGlhbCkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPVQpLC5ncm91cHMgPSAiZHJvcCIpCgoKc3RhdGVfY2hhbmdlIDwtaGlzdG9yaWNfc3BwICU+JSAKICBncm91cF9ieShzdGF0ZSx5ZWFyLHJlZ2lvbixzcHAsc3BhdGlhbCkgJT4lIAogIHN1bW1hcmlzZShzdGF0ZV92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT0gVCksIC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICBsZWZ0X2pvaW4odG90YWxfZml0ZWQsCiAgICAgICAgICAgIGJ5ID0gYygieWVhciIsInJlZ2lvbiIsInNwcCIsInNwYXRpYWwiKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDAsCiAgICAgICAgIGxhYmVsID0gaWZlbHNlKHllYXIgPj0gMTk4MCAmIHllYXIgPD0gMjAwMSwiUmVmZXJlbmNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyID4gMjAwMSwiVG9kYXkiLE5BKQogICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICApICU+JSAKICBncm91cF9ieShzdGF0ZSxsYWJlbCxyZWdpb24sc3BwLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9wZXIgPSByb3VuZChtZWFuKHBlcmNlbnRhZ2UpKSwuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgIyBPbmx5IHNob3cgcmVzdWx0cyBmb3Igc3ByaW5nCiAgZmlsdGVyKHN0cl9kZXRlY3QocmVnaW9uLCJTcHJpbmciKSwKICAgICAgICAgIWlzLm5hKGxhYmVsKQogICAgICAgICApICU+JSAKICBzZWxlY3QoLXJlZ2lvbikgJT4lIAogIHNwcmVhZChsYWJlbCxtZWFuX3BlcikgJT4lIAogIG11dGF0ZShjaGFuZ2UgPSAoVG9kYXktUmVmZXJlbmNlKS8oVG9kYXkpKjEwMCwKICAgICAgICAgY2hhbmdlID0gaWZlbHNlKGNoYW5nZSA+IDEwMCwxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoY2hhbmdlIDwgLTEwMCwtMTAwLGNoYW5nZSkKICAgICAgICAgKQogICkgJT4lCiAgc2VsZWN0KC00LC01KSAlPiUgCiAgc3ByZWFkKHNwYXRpYWwsY2hhbmdlKSAlPiUgCiAgbXV0YXRlKAogICAgI2RpZmZlcmVuY2UgPSAoZnAtc3cpLygoZnArc3cpLzIpKjEwMCwKICAgIGRpZmZlcmVuY2UgPSBhYnMoZnAtc3cpIywKICAgICAgICAgIyBkaWZmZXJlbmNlID0gaWZlbHNlKGRpZmZlcmVuY2UgPiAxMDAsMTAwLAogICAgICAgICAjICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKGRpZmZlcmVuY2UgPCAtMTAwLC0xMDAsZGlmZmVyZW5jZSkKICAgICAgICAgIyApCiAgKSAlPiUgCiAgZ2F0aGVyKCJzcGF0aWFsIiwibWVhbl9wZXIiLGZwOmRpZmZlcmVuY2UpICU+JSAKICBtdXRhdGUoCiAgICAgICAgIHNwYXRpYWwgPSBpZmVsc2Uoc3BhdGlhbCA9PSAiZnAiLCJGaXNoaW5nIHBvcnRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2Uoc3BhdGlhbCA9PSAic3ciLCJTdGF0ZSBXYXRlcnMiLCJEaWZmZXJlbmNlIikKICAgICAgICAgKSwKICAgICAgICAgbWVhbl9wZXI9IHJlcGxhY2VfbmEobWVhbl9wZXIsMCkjIGZvciB0aG9zZSAwLzAKICApCiAgIAoKIyBUaGUgcGxvdApwcm9wX2NobmdfbWFwIDwtIGxhbmRfc2YgJT4lIAogIGxlZnRfam9pbihzdGF0ZV9jaGFuZ2UsCiAgICAgICAgICAgIGJ5ID0gInN0YXRlIikgJT4lIAogIGZpbHRlcihzcGF0aWFsICE9ICJEaWZmZXJlbmNlIikgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gbWVhbl9wZXIpKSArCiAgdmlyaWRpczo6c2NhbGVfZmlsbF92aXJpZGlzKCJDaGFuZ2UgaW4gcHJvcG9ydGlvbiB0b2RheVxucmVsYXRpdmUgdG8gMTk4MC0yMDAxXG4oJSkiLCBhbHBoYSA9IDAuOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygtMTAwLDEwMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgtMTAwLDEwMCwyNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIjwtMTAwIixzZXEoLTc1LDc1LDI1KSwiPjEwMCIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgKwogIGZhY2V0X2dyaWQoc3BhdGlhbH4gc3BwKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICIiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAyMCwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICJib3R0b20iLAogICAgICAgICAgICAgICBheHhfdHhfYW5nID0gNDUsCiAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMiwKICAgICAgICAgICAgICAgYXhfdGxfcyA9IDE4LAogICAgICAgICAgICAgICBoanVzdCA9IDEpICsKICB0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCg0LCJsaW5lIiksCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduPTAuNSkgCgojIGdnc2F2ZShmaWxlbmFtZSA9ICJ0ZW1wX3Byb3BvcnRpb25fY2huZy5qcGciLAojICAgICAgICAgIHBsb3QgPSBwcm9wX2NobmdfbWFwLAojICAgICAgICAgIHBhdGggPSBteV9wYXRoKCJSIiwiRmlndXJlcyIpLAojICAgICAgICAgIHdpZHRoID0gMTAsCiMgICAgICAgICAgaGVpZ2h0ID0gMTAKIyAgICkKCgojIyMjIE9wdGlvbiB3aXRoIGRpZmZlcmVuY2VzCgpwcm9wX2NobmdfbWFwX2RpZmYgPC0gbGFuZF9zZiAlPiUgCiAgbGVmdF9qb2luKHN0YXRlX2NoYW5nZSwKICAgICAgICAgICAgYnkgPSAic3RhdGUiKSAlPiUgCiAgZmlsdGVyKHNwYXRpYWwgPT0gIkRpZmZlcmVuY2UiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBtZWFuX3BlcikpICsKICB2aXJpZGlzOjpzY2FsZV9maWxsX3ZpcmlkaXMoIkNoYW5nZSBpbiBwcm9wb3J0aW9uIHRvZGF5XG5yZWxhdGl2ZSB0byAxOTgwLTIwMDFcbiglKSIsIGFscGhhID0gMC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb24gPSAiQyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gYygtMTAwLDEwMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgtMTAwLDEwMCwyNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIjwtMTAwIixzZXEoLTc1LDc1LDI1KSwiPjEwMCIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgKwogIGZhY2V0X2dyaWQoc3BhdGlhbH4gc3BwKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICIiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAyMCwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICJib3R0b20iLAogICAgICAgICAgICAgICBheHhfdHhfYW5nID0gNDUsCiAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMiwKICAgICAgICAgICAgICAgYXhfdGxfcyA9IDE4LAogICAgICAgICAgICAgICBoanVzdCA9IDEpICsKICB0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCg0LCJsaW5lIiksCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduPTAuNSwKICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkKCgojIENvd3Bsb3Qgb3B0aW9uCnAgPC0gZ2dkcmF3KCkgKwogICMgUmV2ZW51ZSBjaXJjdWxhcgogIGRyYXdfcGxvdChwcm9wX2NobmdfbWFwLCB4ID0gMCwgeSA9IDAuMjUsIHdpZHRoID0gMSwgaGVpZ2h0ID0gMC42NSkgKwogICMgQ2F0Y2ggY2lyY3VsYXIKICBkcmF3X3Bsb3QocHJvcF9jaG5nX21hcF9kaWZmLCB4ID0gMC4xMDEsIHkgPSAwLCB3aWR0aCA9IDAuNzk4LCBoZWlnaHQgPSAwLjQpICsKICBkcmF3X3Bsb3RfbGFiZWwobGFiZWwgPSBjKCJMYXRpdHVkZSIsICJMb25naXR1ZGUiKSwgCiAgICAgICAgICAgICAgICAgIHNpemUgPSAxNiwKICAgICAgICAgICAgICAgICAgYW5nbGUgPSBjKDkwLDApLAogICAgICAgICAgICAgICAgICB4ID0gYygwLjEsMC40NSksIAogICAgICAgICAgICAgICAgICB5ID0gYygwLjQ1LDAuMTEpCiAgKQogICAgCgpzYXZlX3Bsb3QoCiAgcGF0aCA9IG15X3BhdGgoIlIiLCJGaWd1cmVzIiksCiAgInByb3BvcnRpb25fY2hnX2RpZmZOLmpwZyIsCiAgcCwKICBiYXNlX2hlaWdodCA9IDE0LAogIGJhc2Vfd2lkdGggPSAxNAopCgpgYGAKCgojIyMgUHJvcG9ydGlvbiBjaGFuZ2UgcmVhbHRpdmUgdG8gcGFzdAoKYGBge3IgcGFwZXJfZmlndXJlX2FyZWFfbWFwLCBldmFsID0gRiwgZWNobyA9IFQsIHJlc3VsdHM9J2hpZGUnfQoKdG90YWxfZml0ZWQgPC0gaGlzdG9yaWNfc3BwICU+JQogIGdyb3VwX2J5KHllYXIsc2Vhc29uLHNwcCxzcGF0aWFsKSAlPiUKICBzdW1tYXJpc2UodG90YWxfdmFsdWUgPSBzdW0odmFsdWUsbmEucm09VCksLmdyb3VwcyA9ICJkcm9wIikKCgpzdGF0ZV9jaGFuZ2UgPC1oaXN0b3JpY19zcHAgJT4lIAogIGdyb3VwX2J5KHN0YXRlLHllYXIsc2Vhc29uLHNwcCxzcGF0aWFsKSAlPiUgCiAgc3VtbWFyaXNlKHN0YXRlX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPSBUKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lIAogIGxlZnRfam9pbih0b3RhbF9maXRlZCwKICAgICAgICAgICAgYnkgPSBjKCJ5ZWFyIiwicmVnaW9uIiwic3BwIiwic3BhdGlhbCIpKSAlPiUKICBtdXRhdGUocGVyY2VudGFnZSA9IHN0YXRlX3ZhbHVlL3RvdGFsX3ZhbHVlKjEwMCwKICAgICAgICAgbGFiZWwgPSBpZmVsc2UoeWVhciA+PSAxOTgwICYgeWVhciA8PSAyMDAxLCJSZWZlcmVuY2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKHllYXIgPiAyMDAxLCJUb2RheSIsTkEpCiAgICAgICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICkgJT4lIAogIGdyb3VwX2J5KHN0YXRlLGxhYmVsLHJlZ2lvbixzcHAsc3BhdGlhbCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3BlciA9IHJvdW5kKG1lYW4ocGVyY2VudGFnZSkpLC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICAjIE9ubHkgc2hvdyByZXN1bHRzIGZvciBzcHJpbmcKICBmaWx0ZXIoc3RyX2RldGVjdChyZWdpb24sIlNwcmluZyIpLAogICAgICAgICAhaXMubmEobGFiZWwpCiAgICAgICAgICkgJT4lIAogIHNlbGVjdCgtcmVnaW9uKSAlPiUgCiAgc3ByZWFkKGxhYmVsLG1lYW5fcGVyKSAlPiUgCiAgbXV0YXRlKGNoYW5nZSA9IChUb2RheS1SZWZlcmVuY2UpLyhUb2RheSkqMTAwLAogICAgICAgICBjaGFuZ2UgPSBpZmVsc2UoY2hhbmdlID4gMTAwLDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShjaGFuZ2UgPCAtMTAwLC0xMDAsY2hhbmdlKQogICAgICAgICApCiAgKSAlPiUKICBzZWxlY3QoLTQsLTUpICU+JSAKICBzcHJlYWQoc3BhdGlhbCxjaGFuZ2UpICU+JSAKICBtdXRhdGUoCiAgICAjZGlmZmVyZW5jZSA9IChmcC1zdykvKChmcCtzdykvMikqMTAwLAogICAgZGlmZmVyZW5jZSA9IGFicyhmcC1zdykjLAogICAgICAgICAjIGRpZmZlcmVuY2UgPSBpZmVsc2UoZGlmZmVyZW5jZSA+IDEwMCwxMDAsCiAgICAgICAgICMgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoZGlmZmVyZW5jZSA8IC0xMDAsLTEwMCxkaWZmZXJlbmNlKQogICAgICAgICAjICkKICApICU+JSAKICBnYXRoZXIoInNwYXRpYWwiLCJtZWFuX3BlciIsZnA6ZGlmZmVyZW5jZSkgJT4lIAogIG11dGF0ZSgKICAgICAgICAgc3BhdGlhbCA9IGlmZWxzZShzcGF0aWFsID09ICJmcCIsIkZpc2hpbmcgcG9ydHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShzcGF0aWFsID09ICJzdyIsIlN0YXRlIFdhdGVycyIsIkRpZmZlcmVuY2UiKQogICAgICAgICApLAogICAgICAgICBtZWFuX3Blcj0gcmVwbGFjZV9uYShtZWFuX3BlciwwKSMgZm9yIHRob3NlIDAvMAogICkKICAgCgojIFRoZSBwbG90CnByb3BfY2huZ19tYXAgPC0gbGFuZF9zZiAlPiUgCiAgbGVmdF9qb2luKHN0YXRlX2NoYW5nZSwKICAgICAgICAgICAgYnkgPSAic3RhdGUiKSAlPiUgCiAgZmlsdGVyKHNwYXRpYWwgIT0gIkRpZmZlcmVuY2UiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBtZWFuX3BlcikpICsKICB2aXJpZGlzOjpzY2FsZV9maWxsX3ZpcmlkaXMoIkNoYW5nZSBpbiBwcm9wb3J0aW9uIHRvZGF5XG5yZWxhdGl2ZSB0byAxOTgwLTIwMDFcbiglKSIsIGFscGhhID0gMC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKC0xMDAsMTAwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKC0xMDAsMTAwLDI1KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiPC0xMDAiLHNlcSgtNzUsNzUsMjUpLCI+MTAwIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSArCiAgZmFjZXRfZ3JpZChzcGF0aWFsfiBzcHApICsKICBsYWJzKHggPSAiIiwgCiAgICAgICB5ID0gIiIpICsKICBteV9nZ3RoZW1lX3AoZmFjZXRfdHhfcyA9IDIwLAogICAgICAgICAgICAgICBsZWdfcG9zID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgIGF4eF90eF9hbmcgPSA0NSwKICAgICAgICAgICAgICAgYXhfdHhfcyA9IDEyLAogICAgICAgICAgICAgICBheF90bF9zID0gMTgsCiAgICAgICAgICAgICAgIGhqdXN0ID0gMSkgKwogIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDQsImxpbmUiKSwKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ249MC41KSAKCiMgZ2dzYXZlKGZpbGVuYW1lID0gInRlbXBfcHJvcG9ydGlvbl9jaG5nLmpwZyIsCiMgICAgICAgICAgcGxvdCA9IHByb3BfY2huZ19tYXAsCiMgICAgICAgICAgcGF0aCA9IG15X3BhdGgoIlIiLCJGaWd1cmVzIiksCiMgICAgICAgICAgd2lkdGggPSAxMCwKIyAgICAgICAgICBoZWlnaHQgPSAxMAojICAgKQoKCiMjIyMgT3B0aW9uIHdpdGggZGlmZmVyZW5jZXMKCnByb3BfY2huZ19tYXBfZGlmZiA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4oc3RhdGVfY2hhbmdlLAogICAgICAgICAgICBieSA9ICJzdGF0ZSIpICU+JSAKICBmaWx0ZXIoc3BhdGlhbCA9PSAiRGlmZmVyZW5jZSIpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IG1lYW5fcGVyKSkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcygiQ2hhbmdlIGluIHByb3BvcnRpb24gdG9kYXlcbnJlbGF0aXZlIHRvIDE5ODAtMjAwMVxuKCUpIiwgYWxwaGEgPSAwLjgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbiA9ICJDIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKC0xMDAsMTAwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKC0xMDAsMTAwLDI1KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiPC0xMDAiLHNlcSgtNzUsNzUsMjUpLCI+MTAwIikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSArCiAgZmFjZXRfZ3JpZChzcGF0aWFsfiBzcHApICsKICBsYWJzKHggPSAiIiwgCiAgICAgICB5ID0gIiIpICsKICBteV9nZ3RoZW1lX3AoZmFjZXRfdHhfcyA9IDIwLAogICAgICAgICAgICAgICBsZWdfcG9zID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgIGF4eF90eF9hbmcgPSA0NSwKICAgICAgICAgICAgICAgYXhfdHhfcyA9IDEyLAogICAgICAgICAgICAgICBheF90bF9zID0gMTgsCiAgICAgICAgICAgICAgIGhqdXN0ID0gMSkgKwogIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDQsImxpbmUiKSwKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ249MC41LAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQoKCiMgQ293cGxvdCBvcHRpb24KcCA8LSBnZ2RyYXcoKSArCiAgIyBSZXZlbnVlIGNpcmN1bGFyCiAgZHJhd19wbG90KHByb3BfY2huZ19tYXAsIHggPSAwLCB5ID0gMC4yNSwgd2lkdGggPSAxLCBoZWlnaHQgPSAwLjY1KSArCiAgIyBDYXRjaCBjaXJjdWxhcgogIGRyYXdfcGxvdChwcm9wX2NobmdfbWFwX2RpZmYsIHggPSAwLjEwMSwgeSA9IDAsIHdpZHRoID0gMC43OTgsIGhlaWdodCA9IDAuNCkgKwogIGRyYXdfcGxvdF9sYWJlbChsYWJlbCA9IGMoIkxhdGl0dWRlIiwgIkxvbmdpdHVkZSIpLCAKICAgICAgICAgICAgICAgICAgc2l6ZSA9IDE2LAogICAgICAgICAgICAgICAgICBhbmdsZSA9IGMoOTAsMCksCiAgICAgICAgICAgICAgICAgIHggPSBjKDAuMSwwLjQ1KSwgCiAgICAgICAgICAgICAgICAgIHkgPSBjKDAuNDUsMC4xMSkKICApCiAgICAKCnNhdmVfcGxvdCgKICBwYXRoID0gbXlfcGF0aCgiUiIsIkZpZ3VyZXMiKSwKICAicHJvcG9ydGlvbl9jaGdfZGlmZk4uanBnIiwKICBwLAogIGJhc2VfaGVpZ2h0ID0gMTQsCiAgYmFzZV93aWR0aCA9IDE0CikKCmBgYAoKCgoKIyMjIEFnZ3JlZ2F0ZWQgUHJvcG9ydGlvbmFsIGNoYW5nZQoKYGBge3IgYXJlYV9tYXBfYWdncmVnYXRlZF9mb3JtYW5zLCBldmFsID0gVCwgZWNobyA9IFQsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0PTZ9Cgp0b3RhbF9maXRlZCA8LSBoaXN0b3JpY19zcHAgJT4lCiAgZ3JvdXBfYnkoeWVhcixyZWdpb24sc3BhdGlhbCkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX3ZhbHVlID0gc3VtKHZhbHVlLG5hLnJtPVQpLC5ncm91cHMgPSAiZHJvcCIpCgoKc3RhdGVfY2hhbmdlIDwtIGhpc3RvcmljX3NwcCAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUseWVhcixyZWdpb24sc3BhdGlhbCkgJT4lIAogIHN1bW1hcmlzZShzdGF0ZV92YWx1ZSA9IHN1bSh2YWx1ZSxuYS5ybT0gVCksIC5ncm91cHMgPSAiZHJvcCIpICU+JSAKICBsZWZ0X2pvaW4odG90YWxfZml0ZWQsCiAgICAgICAgICAgIGJ5ID0gYygieWVhciIsInJlZ2lvbiIsInNwYXRpYWwiKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRhZ2UgPSBzdGF0ZV92YWx1ZS90b3RhbF92YWx1ZSoxMDAsCiAgICAgICAgIGxhYmVsID0gaWZlbHNlKHllYXIgPj0gMTk4MCAmIHllYXIgPD0gMjAwMSwicmVmZXJlbmNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSh5ZWFyID4gMjAwMSwidG9kYXkiLE5BKQogICAgICAgICAgICAgICAgICAgICAgICAgKQogICAgICAgICApICU+JSAKICAjIGxlZnRfam9pbihwZXJpb2RzLAogICAgICAgICAgICAjIGJ5ID0gInllYXIiKSAlPiUgCiAgZ3JvdXBfYnkoc3RhdGUsbGFiZWwscmVnaW9uLHNwYXRpYWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9wZXIgPSByb3VuZChtZWFuKHBlcmNlbnRhZ2UpKSwuZ3JvdXBzID0gImRyb3AiKSAlPiUgCiAgI09ubHkgc2hvdyByZXN1bHRzIGZvciBzcHJpbmcKICBmaWx0ZXIoI3N0cl9kZXRlY3QocmVnaW9uLCJTcHJpbmciKSwKICAgICAgICAgIWlzLm5hKGxhYmVsKQogICAgICAgICApICU+JSAKICAjIHNlbGVjdCgtcmVnaW9uKSAlPiUgCiAgIyBFc3RpbWF0ZSBwZXJjZW50YWdlIGNoYW5nZQogIHNwcmVhZChsYWJlbCxtZWFuX3BlcikgJT4lIAogIG11dGF0ZShyYXdfY2hhbmdlID0gKHRvZGF5LXJlZmVyZW5jZSkvKHRvZGF5KSoxMDAsCiAgICAgICAgIGNoYW5nZSA9IGlmZWxzZShyYXdfY2hhbmdlID4gMTAwLDEwMCwKICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShyYXdfY2hhbmdlIDwgLTEwMCwtMTAwLHJhd19jaGFuZ2UpCiAgICAgICAgICkKICApICU+JQogIHNlbGVjdCgtcmVmZXJlbmNlLC10b2RheSkgCgoKIyMjIyBBdmVyYWdlCnN0YXRlX2NoYW5nZSAlPiUgCiAgbXV0YXRlKAogICAgd2wgPSBpZmVsc2UoY2hhbmdlIDwgMCwgIkwiLAogICAgICAgICAgICAgICAgaWZlbHNlKGNoYW5nZSA9PSAwLCAiTkMiLCJXIikpCiAgKSAlPiUgCiAgIyBWaWV3KCkKICAjIGdyb3VwX2J5KHdsKSAlPiUgCiAgZ3JvdXBfYnkocmVnaW9uLHNwYXRpYWwsd2wpICU+JSAKICBzdW1tYXJpc2UoCiAgICBzdGF0ZXMgPSBwYXN0ZSh1bmlxdWUoc3RhdGUpLGNvbGxhcHNlID0gIiwgIiksCiAgICBtZWFuKHJhd19jaGFuZ2UpLAogICAgc2QocmF3X2NoYW5nZSkKICApICU+JSAKICB3cml0ZV9jc3YoIi4uL1Jlc3VsdHMvc3RhdGVfcmVsYXRpdmVfY2huZy5jc3YiKQogIFZpZXcoKQoKCgogICMgRXN0aW1hdGUgc3BhdGlhbCBkaWZmZXJlbmNlcyBpbiBwZXJjZW50YWdlIGNoYW5nZQpzcGF0aWFsX2RpZmYgPC0gc3RhdGVfY2hhbmdlICU+JSAKICBzcHJlYWQoc3BhdGlhbCxjaGFuZ2UpICU+JSAKICBtdXRhdGUoc3BhdGlhbF9kaWZmID0gYWJzKGZwLXN3KSkgJT4lIAogIHNlbGVjdChzdGF0ZSwgY2F0ZWdvcnkgPSByZWdpb24sIGRpZmYgPSBzcGF0aWFsX2RpZmYpCgojIEVzdGltYXRlIHNlYXNvbmFsIGRpZmZlcmVuY2VzIGluIHBlcmNlbnRhZ2UgY2hhbmdlCnNlYXNvbl9kaWZmIDwtIHN0YXRlX2NoYW5nZSAlPiUgCiAgc3ByZWFkKHJlZ2lvbixjaGFuZ2UpICU+JSAgCiAgbXV0YXRlKHNlYXNvbl9kaWZmID0gYWJzKGBOb3J0aGVhc3QgVVMgRmFsbGAtYE5vcnRoZWFzdCBVUyBTcHJpbmdgKSkgJT4lIAogIHNlbGVjdChzdGF0ZSxjYXRlZ29yeSA9IHNwYXRpYWwsZGlmZiA9IHNlYXNvbl9kaWZmKQoKZGlmZmVyZW5jZXMgPC0gc2Vhc29uX2RpZmYgJT4lIAogIGJpbmRfcm93cyhzcGF0aWFsX2RpZmYpICU+JSAKICBtdXRhdGUoCiAgICBsYWJlbCA9IGlmZWxzZShjYXRlZ29yeSA9PSAiZnAiLCJGaXNoaW5nIHBvcnRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoY2F0ZWdvcnkgPT0gInN3IiwiU3RhdGUgV2F0ZXJzIixjYXRlZ29yeSkKICAgICAgICAgKQogICkKCiMgRm9yIGluIHRleHQgZGlmZmVyZW5jZXMKZGlmZmVyZW5jZXMgJT4lIAogIGdyb3VwX2J5KGNhdGVnb3J5KSAlPiUKICBzdW1tYXJpc2VfYXQodmFycyhkaWZmKSwKICAgIGMobWVhbiA9IG1lYW4sCiAgICAgIHNkID1zZCwKICAgICAgbWluID0gbWluLAogICAgICBtYXg9IG1heCkpCgoKIyBUaGUgbWFpbiBwbG90CnByb3BfY2huZ19tYXAgPC0gbGFuZF9zZiAlPiUgCiAgbGVmdF9qb2luKHN0YXRlX2NoYW5nZSwKICAgICAgICAgICAgYnkgPSAic3RhdGUiKSAlPiUgCiAgIyBmaWx0ZXIoc3BhdGlhbCAhPSAiRGlmZmVyZW5jZSIgJiBjYXQgIT0gImRpZmZlcmVuY2VfcmVnIikgJT4lIAogIGdncGxvdCgpICsKICBnZW9tX3NmKGFlcyhmaWxsID0gY2hhbmdlKSkgKwogIHZpcmlkaXM6OnNjYWxlX2ZpbGxfdmlyaWRpcygiQ2hhbmdlIGluIHByb3BvcnRpb24gdG9kYXlcbiByZWxhdGl2ZSB0byAxOTczLTE5ODRcbiglKSIsIGFscGhhID0gMC44LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKC0xMDAsMTAwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gc2VxKC0xMDAsMTAwLDI1KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYyhzZXEoLTEwMCw3NSwyNSksIj4xMDAiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsKICBmYWNldF9ncmlkKHNwYXRpYWx+IHJlZ2lvbikgKwogIGxhYnMoeCA9ICIiLCAKICAgICAgIHkgPSAiIikgKwogIG15X2dndGhlbWVfcChmYWNldF90eF9zID0gMjAsCiAgICAgICAgICAgICAgIGxlZ19wb3MgPSAiYm90dG9tIiwKICAgICAgICAgICAgICAgYXh4X3R4X2FuZyA9IDQ1LAogICAgICAgICAgICAgICBheF90eF9zID0gMTIsCiAgICAgICAgICAgICAgIGF4X3RsX3MgPSAxOCwKICAgICAgICAgICAgICAgaGp1c3QgPSAxKSArCiAgdGhlbWUobGVnZW5kLmtleS53aWR0aCA9IHVuaXQoNCwibGluZSIpLAogICAgICAgIGxlZ2VuZC50aXRsZS5hbGlnbj0wLjUsCiAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgKSAKCmdnc2F2ZShmaWxlbmFtZSA9ICJwcm9wb3J0aW9uX2NobmdfYWdnLnBuZyIsCiAgICAgICAgIHBsb3QgPSBwcm9wX2NobmdfbWFwLAogICAgICAgICBwYXRoID0gbXlfcGF0aCgiUiIsIkZpZ3VyZXMiKSwKICAgICAgICAgd2lkdGggPSAxMCwKICAgICAgICAgaGVpZ2h0ID0gMTAKICApCgoKIyMjIyBPcHRpb24gd2l0aCBkaWZmZXJlbmNlcwoKIyBTZWFzb24gZGlmZmVyZW5jY2UKCnNwYXRfZGlmZiA8LSBsYW5kX3NmICU+JSAKICBsZWZ0X2pvaW4oZGlmZmVyZW5jZXMsCiAgICAgICAgICAgIGJ5ID0gInN0YXRlIikgJT4lIAogIGZpbHRlcighY2F0ZWdvcnkgJWluJSBjKCJmcCIsInN3IikpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IGRpZmYpKSArCiAgdmlyaWRpczo6c2NhbGVfZmlsbF92aXJpZGlzKCJEaWZmZXJlbmNlcyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uID0gIkMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsNTApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCw1MCwxMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSArCiAgZmFjZXRfd3JhcCh+IGxhYmVsLAogICAgICAgICAgICAgbmNvbCA9IDIpICsKICBsYWJzKHggPSAiIiwgCiAgICAgICB5ID0gIiIpICsKICBteV9nZ3RoZW1lX3AoZmFjZXRfdHhfcyA9IDIwLAogICAgICAgICAgICAgICBsZWdfcG9zID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgIGF4eF90eF9hbmcgPSA0NSwKICAgICAgICAgICAgICAgYXhfdHhfcyA9IDEyLAogICAgICAgICAgICAgICBheF90bF9zID0gMTgsCiAgICAgICAgICAgICAgIGhqdXN0ID0gMSkgKwogIHRoZW1lKGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDQsImxpbmUiKSwKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ249MC41LAogICAgICAgIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKQoKZ2dzYXZlKGZpbGVuYW1lID0gInNwYXRfZGlmZi5wbmciLAogICAgICAgICBwbG90ID0gc3BhdF9kaWZmLAogICAgICAgICBwYXRoID0gbXlfcGF0aCgiUiIsIkZpZ3VyZXMiKSwKICAgICAgICAgd2lkdGggPSA4LAogICAgICAgICBoZWlnaHQgPSA2CiAgKQoKIyBzZWFzb25hbApzZWFzX2RpZmYgPC0gbGFuZF9zZiAlPiUgCiAgbGVmdF9qb2luKGRpZmZlcmVuY2VzLAogICAgICAgICAgICBieSA9ICJzdGF0ZSIpICU+JSAKICBmaWx0ZXIoY2F0ZWdvcnkgJWluJSBjKCJmcCIsInN3IikpICU+JSAKICBnZ3Bsb3QoKSArCiAgZ2VvbV9zZihhZXMoZmlsbCA9IGRpZmYpKSArCiAgdmlyaWRpczo6c2NhbGVfZmlsbF92aXJpZGlzKCJEaWZmZXJlbmNlcyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uID0gIkMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDAsNTApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoMCw1MCwxMCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSArCiAgZmFjZXRfd3JhcCh+IGxhYmVsLAogICAgICAgICAgICAgbmNvbCA9IDEsCiAgICAgICAgICAgICBzdHJpcC5wb3NpdGlvbj0icmlnaHQiKSArCiAgbGFicyh4ID0gIiIsIAogICAgICAgeSA9ICIiKSArCiAgbXlfZ2d0aGVtZV9wKGZhY2V0X3R4X3MgPSAyMCwKICAgICAgICAgICAgICAgbGVnX3BvcyA9ICIiLAogICAgICAgICAgICAgICBheHhfdHhfYW5nID0gNDUsCiAgICAgICAgICAgICAgIGF4X3R4X3MgPSAxMiwKICAgICAgICAgICAgICAgYXhfdGxfcyA9IDE4LAogICAgICAgICAgICAgICBoanVzdCA9IDEpICsKICB0aGVtZShzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICMgc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpCiAgICAgICAgKQoKZ2dzYXZlKGZpbGVuYW1lID0gInNlYXNfZGlmZi5wbmciLAogICAgICAgICBwbG90ID0gc2Vhc19kaWZmLAogICAgICAgICBwYXRoID0gbXlfcGF0aCgiUiIsIkZpZ3VyZXMiKSwKICAgICAgICAgd2lkdGggPSA4LAogICAgICAgICBoZWlnaHQgPSA2CiAgKQoKCmBgYAoKCgoKYGBge3J9CgoKIyMjIFNSQUggTEFORElORyBEQVRBCiMgcmVhZF9leGNlbF9hbGxzaGVldHMgPC0gZnVuY3Rpb24oZmlsZW5hbWUsIHRpYmJsZSA9IFRSVUUpIHsKIyAgICAgIyBJIHByZWZlciBzdHJhaWdodCBkYXRhLmZyYW1lcwojICAgICAjIGJ1dCBpZiB5b3UgbGlrZSB0aWR5dmVyc2UgdGliYmxlcyAodGhlIGRlZmF1bHQgd2l0aCByZWFkX2V4Y2VsKQojICAgICAjIHRoZW4ganVzdCBwYXNzIHRpYmJsZSA9IFRSVUUKIyAgICAgc2hlZXRzIDwtIHJlYWR4bDo6ZXhjZWxfc2hlZXRzKGZpbGVuYW1lKVsyOjhdCiMgICAgIHggPC0gbGFwcGx5KHNoZWV0cywgZnVuY3Rpb24oWCkgcmVhZHhsOjpyZWFkX2V4Y2VsKGZpbGVuYW1lLCBzaGVldCA9IFgpKQojICAgICBpZighdGliYmxlKSB4IDwtIGxhcHBseSh4LCBhcy5kYXRhLmZyYW1lKQojICAgICBuYW1lcyh4KSA8LSBzaGVldHMKIyAgICAgeAojIH0KIyBHZXQgZGF0YSBwYXRoCiMgcG9ydHNfcGF0aCA8LSBteV9wYXRoKCJEIiwiTk9BQSIsIG5hbWUgPSAiU1NtaXRoXzIwMTUtMjAyMSBMYW5kaW5nc19KVU4gMjAyMS54bHN4IikKCiMgTG9hZCBwb3J0cwojIHBvcnRzX2RhdGEgPC0gYmluZF9yb3dzKHJlYWRfZXhjZWxfYWxsc2hlZXRzKHBvcnRzX3BhdGgpKSAlPiUKIyAgIGNsZWFuX25hbWVzKCkgJT4lCiMgICBtdXRhdGVfaWYoaXMuY2hhcmFjdGVyLAojICAgICAgICAgICAgICAgfiBzdHJfdG9fbG93ZXIoLikpICU+JQojICAgICBmaWx0ZXIoc3BlY2llc19uYW1lICVpbiUgYygic3VtbWVyIGZsb3VuZGVyIiwiYmxhY2sgc2VhIGJhc3MiLCJzY3VwIikpCgpgYGAKCg==